2009-08-11
| 00:00 | lrenn | Apologies if this is a silly idea, but how about version of let that isn't guaranteed sequential but runs the binding forms in a new thread. Call it plet. |
| 00:01 | hiredman | *shrug* |
| 00:02 | hiredman | (let [[a b c d] (pcalls foo bar baz bloop)]) |
| 00:02 | tomoj | there has got to be a better way to do this: https://gist.github.com/faafe19ec35ed632339c |
| 00:02 | tomoj | basically want to map over a bunch of maps, but I'm only interested in changing a deeply nested key |
| 00:03 | hiredman | update-in |
| 00:03 | tomoj | hiredman: awesome. thank you |
| 00:03 | lrenn | hiredman: very nice. thanks. |
| 00:04 | prospero_ | is there a way to test whether something is a particular type of struct-map? |
| 00:05 | hiredman | type tag your struct-maps |
| 00:05 | prospero_ | so there's no implicit metadata? |
| 00:06 | tomoj | I read a mailing list discussion about that a couple days ago |
| 00:06 | tomoj | the type is stored internally but is not accessible, apparently |
| 00:06 | prospero_ | link? |
| 00:06 | prospero_ | oh, well never mind |
| 00:06 | prospero_ | that's a little weird, though |
| 00:06 | hiredman | *shrug* |
| 00:07 | tomoj | the best solution I saw did type tagging with a special constructor function |
| 00:07 | hiredman | that is the why to do it |
| 00:07 | tomoj | you could make a special macro for defining structmaps that built a constructor that tags I suppose |
| 00:08 | dnolen | tomoj: http://github.com/swannodette/spinoza/tree/master all but abandoned, but a point of reference for exactly that. |
| 00:09 | dnolen | i wrote that early in my fiddlings with clojure. i think it's a fairly pointless pursuit now tho. |
| 00:09 | tomoj | why pointless? |
| 00:10 | prospero_ | so is a struct just a well-documented map, then? |
| 00:10 | tomoj | bit faster too I think |
| 00:10 | prospero_ | ok |
| 00:10 | hiredman | well, for the specified keys |
| 00:11 | dnolen | you just get so little from a constructor approach when you have already have robust data types, multi-methods, and hierarchies. |
| 00:11 | dnolen | it's also just un-clojure-y. |
| 00:12 | hiredman | ↑ |
| 00:12 | tomoj | I wonder if my current data structure isn't clojure-y |
| 00:12 | tomoj | I have a seq of maps, keys in which contain seqs of maps, keys in which contain seqs of maps |
| 00:13 | hiredman | sounds gnarly |
| 00:13 | tomoj | update-in helps a little but it's still ugly to twiddle something deep in there |
| 00:14 | dnolen | tomoj: why do you need such deeply nested data? that seems weird in general unless your manipulating xml or something. |
| 00:14 | tomoj | courses have one or more sections, each section has one or more meetings |
| 00:16 | dnolen | tomoj: what doesn't your code look like now that you're using update in? |
| 00:16 | dnolen | update-in |
| 00:21 | tomoj | dnolen: https://gist.github.com/faafe19ec35ed632339c |
| 00:21 | tomoj | not any better really... |
| 00:21 | tomoj | a bit of duplication removed I suppose |
| 00:22 | tomoj | I guess I need map-and-update-in which detects whether the key points to a map or other seq and maps the later keys onto other seqs |
| 00:23 | tomoj | hypothetical use case for a much gnarlier dataset: (map-and-update-in the-courses [:sections :meetings :instructor :grad-students :address] update-grad-student-address) |
| 00:24 | tomoj | looks fun to write.. :/ |
| 00:25 | dnolen | tomoj: why not |
| 00:25 | dnolen | (map #(update-in % [:sections :meetings :time] parse-meeting-time) the-courses) |
| 00:25 | dnolen | might be a typo |
| 00:25 | tomoj | hmm |
| 00:25 | dnolen | oh you want to update every meeting? |
| 00:25 | tomoj | I didn't think update-in worked that way |
| 00:25 | tomoj | indeed |
| 00:26 | tomoj | :sections and :meetings point to lists |
| 00:26 | tomoj | update-in expects only maps |
| 00:26 | tomoj | (I though) |
| 00:26 | dnolen | only partly true |
| 00:26 | dnolen | ,(update-in [1 2 3] [0] inc) |
| 00:26 | clojurebot | [2 2 3] |
| 00:27 | tomoj | ah, right |
| 00:27 | tomoj | but I mean I can't get it to map the update over the list, I think |
| 00:27 | tomoj | the nested lists, I mean |
| 00:32 | JAS415 | map it over nested lists |
| 00:32 | JAS415 | hmm |
| 00:33 | JAS415 | isn't there an assoc-in or something |
| 00:33 | tomoj | less powerful version of update-in, I think |
| 00:33 | tomoj | still doesn't traverse nested lists afaik |
| 00:34 | tomoj | but I think it's a simple function to do what I want, gonna try writing it in a few |
| 00:35 | JAS415 | ,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a 0] inc) |
| 00:35 | clojurebot | {:a [1 1 2 3], :b [4 5 6 7]} |
| 00:36 | JAS415 | ,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a] (fn [x] (map inc x))) |
| 00:36 | clojurebot | {:a (1 2 3 4), :b [4 5 6 7]} |
| 00:37 | JAS415 | ,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a] (fn [x] (map (fn [_] :foo) x))) |
| 00:37 | clojurebot | {:a (:foo :foo :foo :foo), :b [4 5 6 7]} |
| 00:37 | tomoj | JAS415: that's what I'm doing now, https://gist.github.com/faafe19ec35ed632339c/676cbd39a24b8d33908a946b33bb2f5eb1c12820 |
| 00:37 | JAS415 | :-) |
| 00:38 | JAS415 | might consider a helper function to abstract that out |
| 00:38 | tomoj | map-and-update-in :) |
| 00:38 | JAS415 | ya |
| 00:38 | tomoj | gonna write it in a few |
| 00:44 | JAS415 | ,(macroexpand-1 '(-> 1 2 3 4 5)) |
| 00:44 | clojurebot | (clojure.core/-> (clojure.core/-> 1 2) 3 4 5) |
| 00:44 | JAS415 | (macroexpand '(-> 1 2 3 4 5)) |
| 00:45 | JAS415 | ,(macroexpand '(-> 1 2 3 4 5)) |
| 00:45 | clojurebot | (5 (clojure.core/-> (clojure.core/-> (clojure.core/-> 1 2) 3) 4)) |
| 01:00 | JAS415 | ,(list 'defmacro 'created ['p] `(code ...))) |
| 01:00 | clojurebot | (defmacro created [p] (sandbox/code ...)) |
| 01:11 | tomoj | https://gist.github.com/faafe19ec35ed632339c |
| 01:11 | tomoj | probably a prettier way to do it |
| 01:11 | tomoj | I mean, there probably is a prettier way than that gist |
| 01:12 | JAS415 | ah its recursive |
| 01:12 | JAS415 | i see |
| 01:12 | tomoj | I don't plan to nest anything deep enough to blow the stack :) |
| 01:12 | JAS415 | does it change it from a vector to a lazy-seq? |
| 01:13 | tomoj | yeah, because of the map |
| 01:13 | JAS415 | hmm |
| 01:13 | tomoj | I don't care too much right now cus my data isn't vectors anyway |
| 01:13 | JAS415 | ah |
| 01:13 | JAS415 | lazy seqs can get tricky |
| 01:13 | tomoj | I guess (vec (map ..)) solves that? |
| 01:14 | hiredman | (defn map! [func coll] (into (empty coll) (map func coll))) |
| 01:14 | JAS415 | ah cool |
| 01:15 | tomoj | preserves type? |
| 01:15 | hiredman | sort of |
| 01:15 | JAS415 | looks like it |
| 01:15 | JAS415 | do vectors hold metadata? |
| 01:15 | hiredman | ,((fn [func coll] (into (empty coll) (map func coll))) inc #{1 2 3}) |
| 01:15 | clojurebot | #{2 3 4} |
| 01:24 | tomoj | hrmm |
| 01:25 | tomoj | missed a bunch of edge cases |
| 01:25 | tomoj | but... (map-and-update-in the-courses [:sections :meetings :time] parse-meeting-time)) |
| 01:25 | tomoj | woot |
| 01:36 | jwhitlark | Does anyone know how to create an interface, (not implement one), other than gen-interface? The DBus api requires an interface be passed to it so it knows what methods to create on the proxy object. |
| 01:52 | JAS415 | edge cases are always the worst |
| 02:10 | tomoj | graaawwl |
| 02:10 | tomoj | the worst indeed |
| 02:10 | tomoj | I think the number of edge case problems I have is a sign that I'm thinking about this function in the wrong way |
| 02:10 | tomoj | there's probably some simple two liner |
| 04:01 | Anniepoo | clojurebot: paste |
| 04:01 | clojurebot | lisppaste8, url |
| 04:01 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 04:02 | lisppaste8 | Anniepoo pasted "the case of the missing metadata" at http://paste.lisp.org/display/85182 |
| 04:02 | Anniepoo | I'm attempting to add some metadata to some data |
| 04:03 | Anniepoo | it's not getting added |
| 04:03 | arbscht | what is the data? |
| 04:04 | Anniepoo | it's vectors, a long list of them |
| 04:04 | Anniepoo | when I compile the list this code is supposed to be adding some metadata |
| 04:06 | lisppaste8 | Anniepoo annotated #85182 "a shorter version" at http://paste.lisp.org/display/85182#1 |
| 04:06 | Anniepoo | sorry, it's getting late |
| 04:06 | Anniepoo | here's the gist of it |
| 04:06 | arbscht | I think you want with-meta rather than the reader syntax |
| 04:07 | arbscht | ,(map meta (map (fn [x] #{:foo 1} x) [[2] [3]])) |
| 04:07 | clojurebot | (nil nil) |
| 04:07 | arbscht | ,(map meta (map (fn [x] (with-meta x {:foo 1})) [[2] [3]])) |
| 04:07 | clojurebot | ({:foo 1} {:foo 1}) |
| 04:07 | Anniepoo | ok, can you articulate why this is different? |
| 04:08 | Anniepoo | I'm obviously missing something simple about the reader macros |
| 04:10 | arbscht | as I understand it: #^{} is evaluated at read time, when x is a symbol. in with-meta, x is evaluated and metadata is added to the vector |
| 04:10 | Anniepoo | ah! perhaps I'm adding my metadata to the var, not the contents? |
| 04:11 | Anniepoo | 8cD Annie was sorta awake during the clojure talk |
| 04:20 | Anniepoo | whoo hoo, it's printing what looks like the correct gibberish to drive the robot |
| 04:21 | Anniepoo | tomorrow I wire it up |
| 04:22 | Anniepoo | Thanks for all the help, folks |
| 04:22 | clojurebot | for is a loop...in Java |
| 04:23 | tdrgabi | I'm trying to build a sorted-map using a collection of keys & values. I tried (sorted-map '(1 2 3 4)) and (sorted-map [1 2 3 4]). I receive "No value supplied for key: [1 2 3 4]". I tried apply "(sorted-map (apply '(1 2 3 4)))" and received: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn |
| 04:23 | tdrgabi | how can I build the sorted-map ? |
| 04:24 | tdrgabi | i know it works as (sorted-map 1 2 3 4) ... but I have the keys & values in a seq |
| 04:25 | tomoj | tdrgabi: (apply sorted-map keyvals) |
| 04:26 | tdrgabi | tomoj: thank you. |
| 07:23 | paolino | hello folks, I made my mind around this language, without using it,it is targetted to eliminate ruby and python , just I was wondering if it's alive like smalltalk. But yes , amazing is the feature selection, I wish the best for clojure |
| 07:25 | opqdonut | "alive like smalltalk" |
| 07:25 | opqdonut | you are surely joking |
| 07:25 | andyfingerhut | I don't think it has a chance of eliminating Ruby or Python any time soon -- very active development and useful stuff implemented in those languages. |
| 07:25 | andyfingerhut | Nor do I think that was its intent. |
| 07:25 | andyfingerhut | Is Clojure useful, too? Certainly. |
| 07:26 | paolino | opqdonut: I was not, actually :-/ |
| 07:27 | paolino | andyfingerhut: scripting with clojure seems better than both ruby and python, given the jvm |
| 07:27 | clojure | from clojure.org, "... designed to be a general-purpose language ... robust infrastructure for multithreaded programming ...", the latter of which describes neither ruby not python, har har |
| 07:28 | paolino | clojure: exactly, but also lbraries are generally more industrial strength in java |
| 07:29 | paolino | I'm a java detractor also :), but realistic about the libraries |
| 07:31 | paolino | opqdonut: the REPL seems very "alive", but I'm probably "hyped" by the examples |
| 07:32 | opqdonut | ah |
| 07:32 | opqdonut | i thought alive as in the community or development |
| 07:32 | opqdonut | smalltalk is pretty much dead afaict |
| 07:34 | paolino | also being just a haskell fan, I like to create a working GUI interactively, with no gtk2hs and friends, with all the portability problems and building issues |
| 07:34 | paolino | clojure is even simpler then both python and ruby in that sense |
| 08:16 | cemerick | hrm, I hadn't seen this before: java.lang.IllegalArgumentException: recur arg for primitive local: dist must be matching primitive |
| 08:17 | andyfingerhut | You probably have a type declaration like (int ...) or (double ...) in a loop binding, but in the recur, the Clojure compiler doesn't have enough information to determine that the type matches. |
| 08:17 | cemerick | I guess I figured the loop binding would just get boxed if the compiler saw any recurs that provided non-primitive args |
| 08:17 | cemerick | andyfingerhut: yeah, I knew what was going on, just hadn't seen it before :-) |
| 08:23 | cemerick | and actually, the initial loop binding was Double/MAX_VALUE, so I wasn't even thinking about whether the value was primitive or not. |
| 08:24 | andyfingerhut | weird. Doesn't look primitive to me. |
| 08:25 | andyfingerhut | ,(class Double/MAX_VALUE) |
| 08:25 | clojurebot | java.lang.Double |
| 08:25 | andyfingerhut | ,(class (double 5.0)) |
| 08:25 | clojurebot | java.lang.Double |
| 08:25 | andyfingerhut | good enough, I guess |
| 08:25 | cemerick | andyfingerhut: you're passing it to the class fn, which boxes |
| 08:25 | cemerick | it's defined as a "public static final double" in j.l.Double |
| 08:26 | andyfingerhut | are there any writeups about when boxing/unboxing occur in Clojure? Or you just absorb it over time? Or read the source? |
| 08:27 | cemerick | Chouser came up with a utility that reported what types the compiler sees for a particular form. Don't remember where it is, though. |
| 08:27 | cemerick | It was definitely some black majick :-) |
| 08:27 | cemerick | andyfingerhut: there are some odd corner cases, but in general, any function boundary will cause boxing. |
| 08:39 | Chouser | repl-utils/expression-info |
| 08:40 | andyfingerhut | grazie, signoure! |
| 08:40 | andyfingerhut | Um, I mean, thanks. Vacation to Italy makes me want to use two of the 30 words of Italian I know :) |
| 08:41 | Chouser | andyfingerhut: perfectly acceptible. clojurebot has raised the bar on such things. |
| 08:43 | cemerick | Chouser: you'll be happy to know that I've not had to care about zf/auto at all yet. |
| 08:44 | Chouser | cemerick: interesting. I forget -- these are nested vectors? |
| 08:45 | cemerick | no, the primary hierarchy is formed by nested spatial indexes |
| 08:46 | cemerick | mostly neighbor graphs, an RTree here and there |
| 08:49 | Chouser | do you have data in the interior nodes or just at the leaves? |
| 08:49 | cemerick | my query 'language' is pretty tortured at the moment though. I'd like to basically have an xpath-esque syntax, but I've not yet bitten the bullet, so I've got queries like [\\ :foo some-pred] |
| 08:50 | cemerick | Chouser: the former. Every level of the hierarchy is potentially relevant, depending on what's being done. |
| 08:51 | andyfingerhut | OK, this is an example of "give someone an inch, and they'll take a mile", but is there already anything like repl-utils/expression-info, except that it can annotate subexpressions of an entire function definition? |
| 08:52 | Chouser | The reason for zf/auto is so that xml queries don't end up looking like [:html children :head children :body ...] |
| 08:53 | Chouser | xpath uses a plain / for that, but I couldn't find a syntax I liked, so I made it implicit |
| 08:53 | cemerick | yeah, I know. I'm just using / as a proxy for zf/children *shrug* |
| 08:54 | Chouser | andyfingerhut: should be doable -- how would you indicate which sub-expressions you want? or would you just do the whole thing and produce a few pages of output? |
| 08:54 | Chouser | cemerick: oh, ok. well, that's why you haven't had to mess with it then. :-) |
| 08:54 | cemerick | [\\ :foo / :bar / :baz] was good enough for me, as you can't be certain that a :foo predicate should return children or not |
| 08:55 | cemerick | actually, I've written queries like [\\ :foo /], just to return children of :foo's :-P |
| 08:55 | Chouser | cemerick: that may be better anyway. |
| 08:56 | cemerick | Chouser: you don't like using a fn arg from clojure.core as part of your query language? ;-) |
| 08:56 | Chouser | :-P |
| 08:58 | Chouser | andyfingerhut: what would you want to know about each sub-expression? Just primitive true/false? The class also, or even more? |
| 08:58 | Chouser | hm. I think one problem would be indicating which sub-expression each bit of info is talking about. |
| 08:59 | Chouser | by the time the compiler is done with them, the expressions are unprintable and hard to recognize. |
| 08:59 | andyfingerhut | Chouser: Hmmm. I guess what leads me to ask is the desire to find places where there is boxing/unboxing going on that you might not otherwise know about, either because you're relatively new to Clojure (i.e. me still), or because there is a lot of code to look through and tune. |
| 09:00 | andyfingerhut | but flagging other sources of inefficiency besides boxing/unboxing could be useful as well. |
| 09:00 | Chouser | this sort of thing will be much easier after c-in-c |
| 09:01 | Chouser | in fact, then the compiler output will be printable. Not sure how painful it might be to look at, but it'd be easy to get a dump at the repl of everything the compiler has concluded. |
| 09:01 | andyfingerhut | ok. I don't have a burning need for this -- just sounds like something nice to have around. |
| 09:02 | Chouser | ok. then I'll try to stop thinking about it... |
| 09:02 | cemerick | heh, clojure.core/explain :-P |
| 09:02 | Chouser | hiredman: how's the reader coming along? |
| 09:03 | andyfingerhut | It's the kind of thing that people could be pointed at when they want to know how to tune their code, besides *warn-on-reflection* |
| 09:03 | Chouser | reflection is a much bigger cost, but yeah I understand. |
| 09:06 | cemerick | once float and double primitive args are available, a lot of tuning should just go away, I'd think |
| 09:16 | osaunders | Has anyone considered a whitespace sensitive Clojure? |
| 09:17 | andyfingerhut | like Python? |
| 09:17 | osaunders | Sure. |
| 09:17 | osaunders | To cut down on the parens. |
| 09:18 | Chouser | osaunders: yes, but the proposal has the same difficulties as it does for all the lisps |
| 09:18 | osaunders | Chouser: What are those? |
| 09:19 | opqdonut | people always suggest that, then they program in lisp for a while and forget about this perceived need |
| 09:19 | Chouser | specifically, the majority of people who were ever interested in the idea, by the time they know the target language well enough to approach success, stop minding the parens. |
| 09:19 | AWizzArd | ~seen kotarak |
| 09:19 | clojurebot | kotarak was last seen quiting IRC, 921 minutes ago |
| 09:19 | andyfingerhut | Blues Brother movie reference: Jake and Elwood check out an apartment right next to the elevated train in Chicago. Very noisy when it goes by right outside the window. "How often does the train go by?" asks Jake. "So often you won't even notice it," Elwood responds. |
| 09:20 | andyfingerhut | (referring to parens in Lisp) |
| 09:20 | osaunders | Hm, OK. |
| 09:21 | Chouser | somebody did it for CL. Looked pretty good, and it still was never popular. I wonder if I can find a link... |
| 09:21 | osaunders | But there's no technical reason why it can't be done is there? |
| 09:21 | clojurebot | http://clojure.org/rationale |
| 09:21 | cark | the reader is not programmable in clojure |
| 09:21 | cark | so that wouldn't be possible |
| 09:21 | Chouser | osaunders: there are the normal technical challenges, but a pre-processor is entirely possible. |
| 09:22 | opqdonut | aa |
| 09:22 | opqdonut | -aa |
| 09:22 | cark | right, withh a pre-processor, but that would suck big time ! |
| 09:22 | osaunders | Yeah, OK. |
| 09:23 | cark | unless you make a repl too |
| 09:23 | Chouser | not sure how nice whitespace would be at the repl anyway. a bit painful in python. |
| 09:23 | cark | true |
| 09:23 | osaunders | WS doesn't work in REPLs generally, yeah. |
| 09:23 | cark | anyways don't you dare take my parenthesis away =) |
| 09:24 | Chouser | you could also patch the reader directly. would make it a bit more difficult for others to try it out, but it's certainly an option. |
| 09:24 | osaunders | You like typing huh? |
| 09:24 | osaunders | @cark ^ |
| 09:24 | andyfingerhut | http://xkcd.com/297 |
| 09:24 | cark | i like cut/paster full forms with a single keystroke |
| 09:25 | osaunders | What are cut/paster full forms? |
| 09:25 | cark | cut/paste |
| 09:25 | cark | well parenthesis allow for easy editing |
| 09:25 | osaunders | You paste all the parenthesis? |
| 09:25 | cark | and navigating too |
| 09:26 | cark | are you familiar with emacs? (i guess vim is good too) |
| 09:26 | osaunders | Parenthesis denote the data structures. |
| 09:26 | andyfingerhut | cark is probably referring to special features in emacs and vi/vim for selecting/cutting/pasting entire subexpressions at a time |
| 09:26 | osaunders | I would describe indentation as allowing for easy editing. |
| 09:27 | osaunders | I use TextMate mainly. I have a passing familiarity with vim. |
| 09:27 | osaunders | andyfingerhut: Ah, OK. |
| 09:27 | osaunders | Actually that sounds incredibly cool. |
| 09:27 | Chouser | in vim y% copies a whole expression, even without any special support for lisp or clojure. |
| 09:28 | osaunders | But would be achieved with whitespace sensitivity also. |
| 09:28 | osaunders | *could be |
| 09:28 | cark | with these tools, you cut/paste your forms, not thinking about indentation, then let them reindent your code |
| 09:28 | Chouser | there may be something similar in a specail python config file, but I don't know. |
| 09:29 | cark | and most important is the navigation, get inside a form, go two forms forward, dopwn one, delete next form, up up paste |
| 09:30 | cark | too bad i can't express myself in english good enough to convey the fun of it |
| 09:30 | osaunders | cark: It sounds pretty cool actually. |
| 09:30 | cark | the learning curve is pretty steep though |
| 09:31 | andyfingerhut | osaunders: Your idea, or something like it, has been proposed in many variants by many people. While many seem to be turned off by the parens, many are not, and/or get used to them. Some come to love them, especially with nice support in their text editor of choice for handling them. So far, the proposals for fewer parens in Lisp have never caught on among people who do Lisp development. |
| 09:31 | Chouser | osaunders: http://www.dwheeler.com/readable/ |
| 09:32 | cark | right, people have come up with that idea for 50 years, and we still have parenthesis |
| 09:32 | osaunders | lol |
| 09:32 | osaunders | Damn. |
| 09:32 | osaunders | I'm surprised you guys even took me seriously at all. |
| 09:33 | cark | hey there was progress, in clojure we have [] and {} now =) |
| 09:33 | andyfingerhut | not to say it never will, but there is a bit of inertia, or even strong preference, to keep them. |
| 09:34 | andyfingerhut | I've read an article or two somewhere years ago about making source code stored internally in XML or something similar, and then having potentially multiple display formats, depending upon what you were doing, or developer preference. |
| 09:34 | osaunders | :-S |
| 09:35 | osaunders | Sort of like Smalltalk images only with XML. |
| 09:35 | cark | the idea has some merit, but when you want to do macros, you'd rather directly see the parse tree |
| 09:35 | andyfingerhut | I think for a fewer-paren option in a Lisp, to catch on, would probably have to be an option, and have to allow different developers to view it in their preferred style. |
| 09:36 | osaunders | andyfingerhut: Problem with that is that you create a two-tier community. |
| 09:36 | osaunders | Like with braces in C. |
| 09:37 | cark | anyways what's important is the semantics of the language, as opposed to the window dressing |
| 09:37 | andyfingerhut | well, if anyone could look at code written by others in their preferred style, either with a little config, or pressing a button to switch view styles, then the main issue left is all the arguing and name-calling, which I agree is often a bigger problem :) |
| 09:37 | Chouser | cark: I think syntax matters. |
| 09:38 | cark | yes it does, what i mean is that we have something that works pretty well already |
| 09:38 | cark | we're past that |
| 09:38 | Chouser | maybe it shouldn't, or shouldn't matter as much, or we should have tools that automatically convert to our favorite syntax, or whatever. But in practice, today, syntax matters. |
| 09:38 | Chouser | yeah |
| 09:39 | cark | what make clojure great are data structures and concurrency |
| 09:39 | osaunders | Does anyone want to be my learn Clojure buddy? |
| 09:39 | cark | literal syntax for those data structures is a plus, but we could live without it i think |
| 09:41 | cark | speaking of which , does anybody know of a persistent baanced ternary tree implementation for the jvm ? |
| 09:41 | osaunders | Guess not. :-( |
| 09:41 | andyfingerhut | osaunders: What's the pay? :) Seriously, hanging around #clojure might be a decent way -- why have just one teacher? |
| 09:41 | osaunders | andyfingerhut: Hm. OK. I'll stick around. |
| 09:42 | tomoj | osaunders: what does being a learning buddy involve? |
| 09:42 | osaunders | tomoj: Helping each other to learn. Probably just over IRC. |
| 09:43 | osaunders | tomoj: Perhaps both trying to write the same thing in Clojure and then compare solutions. |
| 09:43 | tomoj | that last sounds kinda fun |
| 09:44 | osaunders | We should probably do it in channel so that more experienced people can chime in. |
| 09:44 | tomoj | I'm here most all the time anyway |
| 09:44 | Chouser | there are a bunch of project euler solutions around that are great for that. |
| 09:45 | osaunders | Chouser: Link? |
| 09:45 | tomoj | ah project euler |
| 09:45 | tomoj | had forgotten about that, good idea |
| 09:46 | osaunders | "Mathematical problems" :-S |
| 09:46 | Chouser | oh, not really. more logic than math really. |
| 09:46 | andyfingerhut | I'm growing a collection of solutions to the problems on the language shootout benchmark web site, in Clojure. You can look at them here if you like: http://github.com/jafingerhut/clojure-benchmarks/tree/master |
| 09:46 | andyfingerhut | I've used Scheme and Lisp marginally after learning them 20 years ago, but am newer to Clojure-specific things. |
| 09:47 | tomoj | I think stuff like project euler would be great for getting my head into clojure-space |
| 09:47 | Chouser | I mean, I guess you could solve them using math if you want, but you don't need much math for the first 30 or 40 problems at least. |
| 09:47 | osaunders | Hm. |
| 09:47 | Chouser | A collection of Clojure solutions to PE problems. But don't look until you've tried it -- that's cheating and less fun: http://clojure-euler.wikispaces.com/ |
| 09:49 | andyfingerhut | It can be daunting when you see how much is there. Best to pick one thing that looks interesting, and dive in on just that one. |
| 09:51 | osaunders | OK well I'm going to the pub for a beer. |
| 09:51 | osaunders | And then I'm going to dig in a bit. |
| 09:51 | Chouser | the problems start pretty easy. I found PE to be fun and very educational. |
| 09:51 | osaunders | tomoj: I'm on GTalk if you like. |
| 09:51 | osaunders | and MSN. |
| 09:52 | osaunders | Or maybe just here is better. |
| 09:53 | tomoj | bitlbee kicks me off of gtalk frequently |
| 09:53 | osaunders | Hm, OK. I'll just hang around on here then. |
| 09:53 | tomoj | I've stopped bothering to reconnect |
| 09:53 | osaunders | Alright bbl |
| 10:06 | tomoj | hmm |
| 10:07 | tomoj | oh, "hmm" revoked |
| 10:30 | jayfields | How do I get access to static inner classes? |
| 10:31 | Chouser | pkg.name.Outer$Inner |
| 10:32 | jayfields | thanks Chouser |
| 12:23 | osaunders | ~seen tomoj |
| 12:23 | clojurebot | tomoj was last seen in #clojure, 136 minutes ago saying: oh, "hmm" revoked |
| 12:24 | tomoj | hallo |
| 12:24 | osaunders | Hey |
| 12:24 | osaunders | How much Clojure do you know? |
| 12:25 | tomoj | dunno, not much |
| 12:25 | osaunders | How long have you been doing it? |
| 12:25 | tomoj | I lightly read the "Programming Clojure" book |
| 12:25 | tomoj | been playing around for maybe a week or two |
| 12:26 | osaunders | OK, because today is day 2 for me. |
| 12:26 | osaunders | Do you know what (def blah) does? Without the init part. |
| 12:26 | weissj | osaunders: i started picking it up a few weeks ago, been pretty cool so far |
| 12:27 | weissj | osaunders: it makes it so you can use that var later in the file |
| 12:27 | weissj | otherwise you have to def things before you use them |
| 12:27 | weissj | so you put those (def blah) at the top |
| 12:27 | weissj | maybe there's some other purpose, but that what i've used it for |
| 12:28 | tomoj | sounds right to me |
| 12:28 | osaunders | weissj: Oh. But there's a difference between (def blah) and (def blah nil) isn't there? |
| 12:28 | tomoj | (def blah) leaves blah unboand |
| 12:28 | tomoj | er, unbound |
| 12:28 | osaunders | Right so you'll still get an error if you access it? |
| 12:28 | tomoj | indeed |
| 12:28 | weissj | but i believe that still does the trick - you can now put a reference to blah anywhere in the file |
| 12:29 | weissj | it'll compile at least :) |
| 12:29 | weissj | anywhere below that def, i mean |
| 12:29 | osaunders | Yeah, I don't really see the point in that. |
| 12:29 | cemerick | (declare blah) is more idiomatic for vars you want to establish but not define |
| 12:29 | weissj | osaunders: you'll see, when you start writing functions, you'll have to keep reordering them to make sure the ones at the top level are at the bottom of the file |
| 12:30 | weissj | ie, if a calls b, b must be before a in the file |
| 12:30 | osaunders | weissj: Ah, OK. |
| 12:30 | weissj | using a bunch of defs at the top frees you to use any order |
| 12:30 | osaunders | I'm used to languages where it doesn't care about that. |
| 12:30 | osaunders | -1 for Clojure |
| 12:30 | weissj | yeah, i have heard some talk in this channel of fixing that |
| 12:31 | tomoj | also perhaps you want to use the var only with per-thread bindings |
| 12:31 | tomoj | in that case no reason to give it a root binding |
| 12:31 | cemerick | weissj: Rich said it was *way* more trouble than it's worth a couple of weeks ago. |
| 12:31 | weissj | cemerick: oh ok |
| 12:31 | weissj | it's not that big a deal to me |
| 12:31 | weissj | when other langs have macros, then i'll complain about something like this in clojure :) |
| 12:32 | osaunders | Hehe, yeah. |
| 12:32 | weissj | cemerick: why is it so much trouble? have to add extra passes to the reader i guess |
| 12:33 | weissj | or maybe it does more than 1 pass already? |
| 12:33 | Chousuke | not to the reader, but to the compiler I guess. |
| 12:33 | weissj | Chousuke: oh right |
| 12:33 | cemerick | weissj: I don't know remember what the details were, but at least part of it has to do with name resolution |
| 12:34 | weissj | ok |
| 12:34 | osaunders | I might try the first of this Euler problems. |
| 12:35 | weissj | osaunders: if you haven't got a copy of 'programming clojure' it's really helpful |
| 12:35 | osaunders | http://projecteuler.net/index.php?section=problems&id=1 |
| 12:35 | osaunders | weissj: Yeah I have. Do you think I should read it fully first? |
| 12:35 | weissj | osaunders: no, that's boring :) use it as a reference |
| 12:35 | osaunders | weissj: OK, good. |
| 12:36 | weissj | it also helps to know where to look for stuff on the clojure website. for instance, "syntax" stuff like what does the # symbol mean, etc, that's on the Reader page. |
| 12:36 | tomoj | how do you get a PersistentList of Characters back into a String? Java? |
| 12:37 | weissj | str doesn't do it? |
| 12:37 | tomoj | no :( |
| 12:37 | weissj | it should :) |
| 12:37 | tomoj | ,(str '(\f \o \o)) |
| 12:37 | clojurebot | "(\\f \\o \\o)" |
| 12:37 | weissj | wow, that's unexpected |
| 12:37 | tomoj | I don't know if it should |
| 12:38 | tomoj | it would have to go through every list it was ever passed to check whether that list is a list of only Characters |
| 12:38 | weissj | yeah maybe not, if it's supposed to turn a list into a string representation of the list |
| 12:38 | tomoj | on the other hand, |
| 12:38 | tomoj | ,(str \f \o \o) |
| 12:38 | clojurebot | "foo" |
| 12:38 | tomoj | ..and thus |
| 12:38 | weissj | map it |
| 12:38 | tomoj | ,(apply str '(\f \o \o)) |
| 12:38 | clojurebot | "foo" |
| 12:38 | weissj | apply rather :) |
| 12:39 | nachtalp | hi everybody |
| 12:39 | osaunders | Might be a shorthand for (apply str ()) |
| 12:39 | osaunders | nachtalp: Hi! |
| 12:40 | tomoj | I got a bit of a head start |
| 12:40 | tomoj | :) |
| 12:40 | tomoj | wanna compare solutions? |
| 12:41 | osaunders | I'll probably take ages. My friend is talking to me also. |
| 12:41 | osaunders | Sure, when I'm done :-) |
| 12:41 | nachtalp | does anybody have experience using clojureql? seems i'm not getting the way i'm supposed to deal with result sets properly... |
| 12:42 | osaunders | tomoj: Constructing a range first? |
| 12:43 | weissj | osaunders: that's seems the easiest to me |
| 12:44 | tomoj | osaunders: I didn't use range, but that's a perfectly valid way |
| 12:44 | tomoj | I like to be lazy :) |
| 12:44 | osaunders | I'm not really sure what approach to take because I'm thinking in imperative terms |
| 12:44 | tomoj | though since you have to sum them all up anyway it doesn't really matter I suppose |
| 12:45 | tomoj | except maybe my way won't blow the heap if you summed it up to HUGE numbers |
| 12:45 | weissj | osaunders: think of the range 1..1000 as a set, you're testing each member, then adding the numbers that pass the test |
| 12:45 | weissj | range isn't lazy? |
| 12:45 | osaunders | Oh I have an idea! |
| 12:45 | weissj | ,(doc range) |
| 12:45 | clojurebot | "([end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0 and step to 1." |
| 12:46 | tomoj | oh, you're right |
| 12:46 | tomoj | guess my way is just more verbose then |
| 12:46 | osaunders | ,(reduce + (range 0 100)) |
| 12:46 | clojurebot | 4950 |
| 12:46 | osaunders | Now I just need to filter. |
| 12:46 | weissj | osaunders: you've pretty much got it |
| 12:46 | weissj | well, except the filter function :) |
| 12:58 | osaunders | Hm, I think I have my parens mixed up here. |
| 12:58 | weissj | osaunders: paren-matching editor is a must have :) |
| 12:59 | tomoj | paredit-mode is a must have :P |
| 12:59 | weissj | tomoj: what's that |
| 12:59 | tomoj | emacs mode for editing lispish things |
| 13:00 | technomancy | paredit is badass |
| 13:00 | weissj | tomoj: yeah i know emacs has good support but i just can't bring myself to start learning another obscure editor command set |
| 13:00 | tomoj | maybe other editors can barf/slurp, I dunno |
| 13:01 | osaunders | Can you re-def something in the REPL? |
| 13:01 | weissj | osaunders: yep |
| 13:01 | osaunders | OK, good. |
| 13:02 | weissj | osaunders: for euler problems you can probably use just the repl |
| 13:03 | osaunders | I think I have a solution but it isn't compiling |
| 13:03 | tomoj | doesn't sound like a solution then |
| 13:03 | osaunders | ,(doc if) |
| 13:03 | clojurebot | "/;nil; " |
| 13:04 | tomoj | special form |
| 13:04 | osaunders | Yeah, by "a solution" I mean "a broken". |
| 13:04 | osaunders | I have a broken. |
| 13:04 | tomoj | http://clojure.org/special_forms#toc2 |
| 13:05 | osaunders | tomoj: thnx |
| 13:07 | osaunders | OK I have 2318 |
| 13:07 | tomoj | nope :( |
| 13:07 | osaunders | That's wrong? |
| 13:08 | tomoj | indeed |
| 13:08 | osaunders | Does seem quite high. |
| 13:08 | tomoj | for problem one you mean? |
| 13:08 | osaunders | Yeah. |
| 13:08 | tomoj | it's too low |
| 13:08 | osaunders | Oh |
| 13:08 | osaunders | 233168? |
| 13:08 | tomoj | ja |
| 13:08 | osaunders | Yay! :-) |
| 13:09 | tomoj | can't you type it in or something? |
| 13:09 | osaunders | Seeded the range wrong |
| 13:09 | tomoj | I haven't gotten past the ones I'd already solved before in other languages yet |
| 13:10 | osaunders | You've already done #1 then I guess. |
| 13:10 | tomoj | yep |
| 13:10 | osaunders | So that was what you meant by head start. |
| 13:11 | tomoj | well, that and I also started working on them in clojure before you |
| 13:11 | tomoj | on number 5 now |
| 13:11 | osaunders | http://pastebin.com/m3d47796 |
| 13:12 | tomoj | http://gist.github.com/165965 |
| 13:13 | osaunders | Wow. |
| 13:13 | osaunders | Nice/ |
| 13:13 | osaunders | What does the # mean? |
| 13:13 | osaunders | Meta or something? |
| 13:13 | Chousuke | anonymous function |
| 13:14 | Chousuke | #(foo) is short for (fn [] (foo)) |
| 13:14 | tomoj | with % as the arg |
| 13:14 | tomoj | or %1, %2, etc |
| 13:14 | osaunders | :-O |
| 13:14 | Chousuke | (and %& for the "rest" arg) |
| 13:14 | osaunders | OK. |
| 13:15 | cark | tomoj : just a little thing : (dec n) instead of (- n 1) |
| 13:15 | tomoj | cark: ah, thanks |
| 13:15 | cark | and zero? instead of (= x 0) |
| 13:15 | tomoj | that's nice too |
| 13:16 | osaunders | Thnx cark. |
| 13:16 | Chousuke | osaunders: btw, to avoid having to nest ifs, learn the cond form |
| 13:17 | osaunders | ,(doc cond) |
| 13:17 | clojurebot | "([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil." |
| 13:18 | osaunders | Kinda like switch |
| 13:18 | Chousuke | not really. |
| 13:18 | Chousuke | (cond test expr test2 expr test3 expr3 :else expr4) |
| 13:18 | osaunders | Why have if at all? |
| 13:19 | Chousuke | cond is based on if |
| 13:19 | osaunders | Couldn't you just go straight to cond? |
| 13:19 | Chousuke | ,(macroexpand '(cond test expr)) |
| 13:19 | clojurebot | (if test expr (clojure.core/cond)) |
| 13:19 | tomoj | (if pred foo bar) is cooler than (cond pred foo :else bar) |
| 13:19 | osaunders | Ah yes, OK. |
| 13:20 | Chousuke | ,(macroexpand '(cond test expr test2 expr)) |
| 13:20 | clojurebot | (if test expr (clojure.core/cond test2 expr)) |
| 13:20 | Chousuke | recursive macros ftw |
| 13:20 | Chousuke | oh, and :else is the idiomatic form of an "always true" test, not special syntax. |
| 13:21 | tomoj | better than 't |
| 13:21 | Chousuke | yeah, though it would work as well. :p |
| 13:21 | tomoj | Chousuke: while you're at it, do you know what the heck condp is for? |
| 13:21 | osaunders | Chousuke: Yeah |
| 13:22 | tomoj | I've read the docs several times but it seems very strange |
| 13:22 | cark | (condp = (get-the-keyword) :a (println "got an a")) |
| 13:22 | hiredman | ,(condp = 1 1 :foo 2 :bar) |
| 13:22 | clojurebot | :foo |
| 13:22 | hiredman | ,(condp = 2 1 :foo 2 :bar) |
| 13:22 | clojurebot | :bar |
| 13:23 | osaunders | ,({1 :foo, 2 :bar} 1) |
| 13:23 | clojurebot | :foo |
| 13:24 | osaunders | ,({1 :foo, 2 :bar} 2) |
| 13:24 | clojurebot | :bar |
| 13:24 | tomoj | hrmm |
| 13:24 | osaunders | hiredman: Similar? |
| 13:24 | hiredman | no |
| 13:24 | osaunders | Oh I guess condp has the = thing. |
| 13:24 | hiredman | condp is more like a switch statement |
| 13:24 | hiredman | ,(condp < 1 1 :foo 2 :bar) |
| 13:24 | clojurebot | java.lang.IllegalArgumentException: No matching clause: 1 |
| 13:24 | tomoj | but you get to decide the comparison |
| 13:24 | tomoj | that's pretty nifty |
| 13:25 | hiredman | ,(condp > 1 1 :foo 2 :bar) |
| 13:25 | clojurebot | :bar |
| 13:25 | Chousuke | condp is for cases where the cond test expressions are always of the form (predicate expr someconstantexpr) |
| 13:25 | tomoj | yeah I think I see it now |
| 13:25 | Chousuke | eg, (= 1 (get-choice)), (= 2 (get-choice)) etc. |
| 13:26 | tomoj | don't get the deal with the :>> unary function |
| 13:26 | tomoj | what kind of unary function would you call on the result of a predicate? |
| 13:26 | Chousuke | tomoj: the predicate can return other than true or false. |
| 13:26 | tomoj | sure, but I guess I just can't think of a usage example |
| 13:26 | cark | tomoj : also (take (- 10 1) (iterate inc 1)) is = to (range 1 10) |
| 13:27 | tomoj | cark: yeah, I had thought range wasn't lazy |
| 13:27 | Chousuke | tomoj: for example, maps can work as a predicate |
| 13:27 | clojurebot | for is a loop...in Java |
| 13:28 | Chousuke | tomoj: because if the value exists in the map, it's returned, and is usually non-false. |
| 13:28 | Chousuke | tomoj: and using :>>, you can also use the value retrieved in the result expression, without the need to look it up again |
| 13:32 | osaunders | is camelCase commonplace in Clojure? |
| 13:32 | cark | nope we use lisp-case |
| 13:32 | osaunders | Hypens? |
| 13:32 | cark | yes |
| 13:32 | tomoj | camelCase just for java interop |
| 13:33 | osaunders | Hypens are much better than underscores. |
| 13:33 | osaunders | Anyway, so now that I've got my Euler #1 working can I write a test to prove that it is? |
| 13:34 | osaunders | Do you guys do that sort of thing. |
| 13:35 | tomoj | osaunders: see http://github.com/richhickey/clojure/blob/master/src/clj/clojure/test.clj |
| 13:40 | osaunders | tomoj: ok |
| 13:42 | tomoj | hmm.. problem number 8 is puzzling |
| 14:17 | osaunders | Is there a difference between ; and ;;? |
| 14:17 | andyfingerhut | style |
| 14:17 | duck11232 | emacs indents them differently |
| 14:17 | andyfingerhut | semi-idiomatic to use ;; for a full line comment |
| 14:17 | andyfingerhut | ; for a comment at the end of a line after some code |
| 14:18 | andyfingerhut | but the first ; make everything else a comment. |
| 14:18 | osaunders | OK, thanks. |
| 14:32 | bradford | I find that I would often like to destructure the arg to a fun but also be able to let bind the structured arg as well, becasue i need to refer to both within the fn. any ideas? |
| 14:39 | Chouser | ,(let [[a b :as all] [1 2 3 4]] {:a a, :b b, :all all}) |
| 14:39 | clojurebot | {:a 1, :b 2, :all [1 2 3 4]} |
| 14:39 | brool | bradford: there's the :as keyword for destructuring, is that what you want? |
| 14:44 | bradford | brool, thanks, exactly! |
| 14:44 | bradford | oh wait, Chouser was forst on the ball with that one, thanks Chouser |
| 14:44 | bradford | and as always, thanks be to clojurebot |
| 14:45 | Chouser | clojurebot: botsnack! |
| 14:45 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 14:47 | bradford | ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all |
| 14:47 | bradford | all}) |
| 14:48 | bradford | ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all all}) |
| 14:48 | bradford | even works on maps, cool |
| 14:48 | bradford | ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all all}) |
| 14:48 | clojurebot | {:a 1, :b 2, :all {:a 1, :b 2, :c 3}} |
| 14:48 | bradford | there we go :-) |
| 14:49 | bradford | damn leading whitespace |
| 14:49 | cark | ,(let [{:keys [a b c]} {:a 1 :b 2}] (+ a 2)) |
| 14:49 | clojurebot | 3 |
| 14:49 | cark | i like that form better |
| 14:51 | bradford | yea, i have used both and not sure my fav way for map destructuring yet. i was thinking of creating a new fn that works with vector or map of params by default, so doesn't require any :keys or {} destructuring...I think I saw that someone had creted something like this |
| 14:55 | tomoj | does reduce hold the head of a lazy seq? |
| 14:56 | Chousuke | no |
| 14:56 | tomoj | great |
| 15:35 | tomoj | I have created a monster http://gist.github.com/166067 |
| 15:36 | hiredman | which one is that? |
| 15:36 | tomoj | 20x20 grid, max product along a diagonal or up/down left/right |
| 15:37 | Chousuke | tomoj: I think that's pretty good. |
| 15:37 | tomoj | maybe breaking it up into smaller functions would make it look less monstrous |
| 15:38 | tomoj | or maybe clojure still just looks opaque to me |
| 15:38 | hiredman | I think I have about 15 functions I defined to help solve problem 11 |
| 15:38 | Chousuke | tomoj: I'm finding it harder to describe it in english than in clojure :p |
| 15:39 | hiredman | ~hiredmans euler.clj |
| 15:39 | clojurebot | hiredmans euler.clj is so embarassing |
| 15:39 | Chousuke | for all groups of four numbers, collect their product and return the maximum of the resulting set? |
| 15:40 | tomoj | yup, where "group" is a diagonal or up/down left/right |
| 15:40 | Chousuke | yeah. |
| 15:40 | Chousuke | I think your code is not a monster as I could tell that much from it. :P |
| 15:40 | Chouser | which problem # |
| 15:40 | tomoj | 11 |
| 15:41 | tomoj | if I showed that code to any of my friends in CS I think they'd run screaming |
| 15:41 | Chousuke | heh |
| 15:41 | Chousuke | and I thought it was simple :P |
| 15:42 | Chousuke | then again, your friends in CS probably could code up algorithms that would make me run away screaming |
| 15:42 | tomoj | maybe not, I guess they were forced to learn haskell and lambda calculus etc after I left CS |
| 15:43 | tomoj | is (filter identity ..) idiomatic? |
| 15:44 | tomoj | I always feel funny when I do it |
| 15:44 | hiredman | there is always (remove nil? …) |
| 15:45 | Chouser | (filter identity ...) is fine |
| 15:45 | tomoj | (remove nil? ...) seems more readable |
| 15:45 | tomoj | since that's exactly what I'm always trying to do |
| 15:45 | Chouser | they don't mean the same |
| 15:46 | hiredman | close |
| 15:46 | tomoj | (filter identity ...) will also remove false? |
| 15:46 | Chouser | ,(filter identity [0 1 false nil 2 3]) |
| 15:46 | clojurebot | (0 1 2 3) |
| 15:46 | Chouser | ,(remove nil? [0 1 false nil 2 3]) |
| 15:46 | clojurebot | (0 1 false 2 3) |
| 15:46 | hiredman | for project euler it is pretty easy to pretend true/false don't exist |
| 15:46 | Chousuke | hmm |
| 15:48 | Chousuke | you could add a :let [line ...] in the for and use :when (not-outside-bounds line) |
| 15:48 | hiredman | my euler.clj has lazy-cons all over the place |
| 15:48 | Chouser | oops |
| 15:49 | tomoj | Chousuke: ah, nice |
| 15:49 | tomoj | I still haven't figured out all the little options on the different binding forms |
| 15:50 | Chousuke | for is a multitool .P |
| 15:52 | Chousuke | it does loop, let, filter, take-while all in one |
| 15:52 | Chousuke | where loop is not really loop but anyway |
| 15:53 | Chousuke | the implementation of for is also rather daunting :P |
| 15:53 | Chouser | tomoj: not shabby at all. |
| 15:54 | tomoj | jeez |
| 15:54 | tomoj | daunting indeed |
| 15:54 | tomoj | it looks like it's trying to be ascii art |
| 15:54 | Chouser | and it needs chunking support now. |
| 15:54 | Chousuke | rhickey did request a chunked-seq version of it, and I thought I could do it, but then I saw it and decided to do something else... |
| 15:55 | Chousuke | so now I'm writing a reader :P |
| 15:55 | Chouser | Chousuke: oh, are you? |
| 15:55 | Chouser | for c-in-c? |
| 15:55 | tomoj | :O |
| 15:55 | tomoj | I always thought you two were the same person |
| 15:55 | Chousuke | yeah. Though I'm not sure if it'll turn out good enough to be actually usable. |
| 15:56 | Chousuke | I also have an implementation of syntax-quote as a macro. |
| 15:56 | Chousuke | though I haven't tested it yet :P |
| 15:57 | Chousuke | http://github.com/Chousuke/clojure/commits/clojure-reader |
| 15:57 | hiredman | testing a reader seems to be a bit of a bugger |
| 15:57 | Chousuke | not usable yet. |
| 15:57 | hiredman | http://github.com/hiredman/reader/blob/49959a987394c08183c69888b637645c657646d0/hiredman/reader.clj |
| 15:58 | Chousuke | heh |
| 15:58 | hiredman | I think mine works, but only because it calls out to LispReader |
| 15:58 | Chousuke | my reader avoids using java calls |
| 15:58 | Chousuke | currently, it wants a sequence of lines. |
| 15:59 | hiredman | my plan is/was to slowly remove all wall-hack calls to LispReader |
| 15:59 | hiredman | very pedestrian |
| 15:59 | Chousuke | heh. |
| 16:00 | Chousuke | I decided I didn't want to bother with state in my reader, so I'm hoping I actually never need to "unread" the underlying stream. |
| 16:01 | hiredman | well the reader can return a pair of what was read and what remains of the input |
| 16:01 | Chousuke | which is what my reader does. |
| 16:02 | hiredman | excellent |
| 16:03 | Chousuke | I'm a bit worried about stack space consumption though. |
| 16:03 | Chouser | you're using recursion? |
| 16:04 | Chousuke | my reader blows up if you have a nested list some hundreds over 2000 deep |
| 16:04 | Chouser | haha |
| 16:04 | hiredman | time for trampoline? |
| 16:04 | Chousuke | the java reader blows up around 9000 |
| 16:04 | cark | i think it's ok =/ |
| 16:04 | Chouser | Chousuke: stop worrying. |
| 16:04 | Chousuke | Chouser: I have postponed most of the worrying until the reader is in somewhat usable state :) |
| 16:05 | Chouser | good |
| 16:05 | Chousuke | if someone needs to read hugely nested things they can just increase the stack space anyway! |
| 16:06 | cark | won't a reader in clojure be too slow though ? |
| 16:06 | Chousuke | I'm not worrying about that either, yet :) |
| 16:07 | cark | right, premature optimization ... |
| 16:07 | Chousuke | I don't think reading is a common operation though. |
| 16:07 | hiredman | cark: that depends on all kinds of things |
| 16:07 | Chousuke | of course, it'll impact startup time. |
| 16:07 | cark | it is common to me ! |
| 16:07 | cark | i use it for data files |
| 16:07 | hiredman | actually a lot of LispReader is implemented using AFns |
| 16:08 | hiredman | each AFn being a "reader macro" |
| 16:08 | hiredman | and there is a dispatch table for selecting reader macros |
| 16:08 | Chousuke | hm |
| 16:08 | Chousuke | now I notice my syntax-quote still doesn't work :( |
| 16:09 | Chousuke | I need to move doall up in core.clj it seems :P |
| 16:09 | hiredman | I am leary of the idea of syntax-quote as a macro |
| 16:09 | Chousuke | it is a macro in most lisps isn't it? |
| 16:09 | Chousuke | only called quasi-quote or something. |
| 16:10 | hiredman | Chousuke: I could just be mistrustful of change |
| 16:10 | Chousuke | but... I think core.clj could use a reorganisation. Moving some of the little java wrappers in their own file would probably help a lot :P |
| 16:10 | Chouser | rhickey wants it moved out of read time |
| 16:10 | hiredman | Chouser: so I should get over it I guess |
| 16:11 | Chousuke | there are so many functions that are just (instance? whatever ...) |
| 16:11 | Chousuke | or (clojure.lang.RT/Whatever ...) |
| 16:11 | Chouser | macroable? |
| 16:13 | Chousuke | Chouser: no, but could be moved into core_host.clj or something |
| 16:13 | Chousuke | it's annoying to put new things in core and having to move many of the little wrappers up because they're defined later than necessary :P |
| 16:33 | tomoj | hmm |
| 16:33 | tomoj | someone's brute force C/C++ solution to problem 14 too 29 hours |
| 16:34 | tomoj | s/too/took/ |
| 16:34 | tomoj | mine took a couple minutes in clojure |
| 16:34 | tomoj | and I searched quadruple the search space unnecessarily |
| 16:34 | tomoj | odd.. |
| 16:35 | Chouser | that's the other side of the high-level/low-level language performance discussion. |
| 16:35 | tomoj | you can be stupid with low-level language? |
| 16:36 | Chousuke | "how easy is it to write the faster algorithm"? :) |
| 16:36 | tomoj | ah |
| 16:36 | Chouser | Chousuke: right |
| 16:37 | Chouser | if a more efficient algorithm means I have to worry about memory ownership, multiple classes to hold different pieces of internal data, etc. it easier to just write the slower algorithm. |
| 17:02 | tomoj | can you use lazy-seq to make a seq where each element is a function of all the previously generated elements? |
| 17:02 | tomoj | mathematical function, I mean, not clojure function |
| 17:04 | Chouser | yes |
| 17:04 | Chouser | :-) |
| 17:04 | hiredman | you just need a reference to the head of the seq |
| 17:05 | tomoj | ah, I see |
| 17:05 | hiredman | or to carry around the intermediate results |
| 17:05 | hiredman | depending on the function |
| 17:08 | hiredman | http://clj-me.blogspot.com/2008/06/primes.html <-- example using lazy-cons |
| 17:09 | tomoj | no longer exists, right |
| 17:09 | hiredman | yeah |
| 17:10 | hiredman | this is just an example, you have to interprolate to a modern approach |
| 17:11 | AWizzArd | http://lambda-the-ultimate.org/node/3560 |
| 17:12 | Chouser | your mathematical function actually needs all the previous values, or just the result of applying itself to all the previous values? |
| 17:12 | hiredman | AWizzArd: excellent |
| 17:13 | tomoj | now that I think about it a bit more |
| 17:13 | tomoj | it either needs all the previous values, or a related calculated value |
| 17:13 | tomoj | which is not the value that goes in the seq |
| 17:13 | AWizzArd | Clojure is even preparing at least to some extent to these vector units |
| 17:14 | Chouser | ok, it's pretty common to use recur or iterate and the filter out what you want in a later chain... |
| 17:14 | Chouser | clojure's better at describing this than english |
| 17:14 | clojurebot | clojure is the best way to learn java |
| 17:15 | tomoj | I think I have done stuff like that before |
| 17:15 | tomoj | just not lazily |
| 17:15 | Chouser | (map first (reduce (fn [[return-val internal-val]] [compute-return compute-internal]) ...)) |
| 17:16 | Chouser | or if you have no input seq, use iterate instead of reduce |
| 17:18 | tomoj | Chouser: thanks... I think I need sleep |
| 17:18 | tomoj | something is not clicking |
| 17:20 | tomoj | ah, found lazy-seq-fibo in programming clojure |
| 17:21 | Chouser | well, that may be more helpful than this, but since I don't know what you're actually trying to do: |
| 17:21 | Chouser | (take 10 (map first (iterate (fn [[rv iv]] [(- iv 2) (* iv 3)]) [:foo 1]))) |
| 17:21 | Chouser | ,(take 10 (map first (iterate (fn [[rv iv]] [(- iv 2) (* iv 3)]) [:foo 1]))) |
| 17:21 | clojurebot | (:foo -1 1 7 25 79 241 727 2185 6559) |
| 17:21 | tomoj | that actually looks about right |
| 17:22 | tomoj | with appropriate substitutions |
| 17:22 | tomoj | thanks |
| 17:24 | Chouser | though if each internal value depends only on the previous, and the return value depends only on one internal value (as in that example), it's probably cleaner to use two links in the seq chain: |
| 17:24 | Chouser | ,(take 10 (map #(- % 2) (iterate #(* % 3) 1))) |
| 17:24 | clojurebot | (-1 1 7 25 79 241 727 2185 6559 19681) |
| 17:24 | b4taylor | I wish to create a byte[] for java.io.FileInputStream.read(byte[]), is make-array the way to go about doing this? |
| 17:25 | Chousuke | into-array might be easier |
| 17:25 | Chousuke | hmm |
| 17:25 | Chousuke | or not, if you want an empty one :) |
| 17:25 | b4taylor | I need an empty one. |
| 17:25 | Chousuke | then make-array, yeah |
| 17:25 | b4taylor | So my problem arising when I need to give it the type to create. |
| 17:26 | Chousuke | use Byte/TYPE |
| 17:26 | b4taylor | (make-array byte 256) gives me a cast exception saying byte is the clojure type. |
| 17:26 | b4taylor | Ah ok. |
| 17:26 | b4taylor | Sweet. |
| 17:26 | b4taylor | Thanks. |
| 17:29 | b4taylor | Oh crud, unsigned bytes. Forgot about that :p |
| 18:35 | andyfingerhut | I know about #^ints, #^doubles, etc. for type hints of Java arrays of primitives. I also know that I can use #^"[Ljava.lang.Object;" as a type hint for a Java array of Objects, but is there a nicer name for that? It seems to help speed up aget/aset on such arrays. |
| 18:42 | Chousuke | andyfingerhut: not yet. :P |
| 18:42 | andyfingerhut | ok, no big deal. |
| 19:00 | hiredman | ~literal [1] problem |
| 19:00 | clojurebot | <reply>People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems.... |
| 19:01 | burkelibbey | Heh, I multiplied two complex numbers with regular expressions once to avoid writing a script in bash >_> |
| 19:02 | burkelibbey | summary: I agree with clojurebot. |
| 19:05 | JAS415 | haha |
| 19:06 | burkelibbey | So I think this is largely because I have a poor understanding of how namespaces work, but: http://gist.github.com/166172 |
| 19:07 | burkelibbey | I'm trying to write a macro to load application.controllers.X and run the invoke method in it |
| 19:07 | burkelibbey | Is that a horrible idea, or am I missing something, or...? Help appreciated :P |
| 19:07 | Chousuke | you're trying to use namespaces as a plugin mechanism? |
| 19:07 | burkelibbey | s/method/function |
| 19:08 | burkelibbey | I guess, yeah |
| 19:08 | Chousuke | yeah, I think that's not such a good idea :P |
| 19:09 | burkelibbey | is there a way to automatically load all the sub-namespaces of another namespace, without hard-coding the whole list? |
| 19:09 | Chousuke | not really. |
| 19:10 | burkelibbey | I guess I'd have to just look through the filesystem |
| 19:10 | burkelibbey | bah |
| 19:10 | Chousuke | subnamespaces are not related to their parent namespaces in any way other than the common part of the path |
| 19:10 | burkelibbey | ok |
| 19:11 | Chousuke | if you need a plugin mechanism, multimethods might be useful |
| 19:12 | Chousuke | each plugin could just do a defmethod on some common multimethod |
| 19:12 | burkelibbey | hmm, yeah, there's an idea. |
| 19:12 | andyfingerhut | I love clojurebot's brain. So much more interesting than Eliza. |
| 19:12 | burkelibbey | thanks |
| 19:15 | duck1123 | are there any good projects to look at that do a lot with command line params in clojure? |
| 19:16 | duck1123 | I had hope with corkscrew, but it does a lot of it in sh, and that's not what I want |
| 19:32 | andyfingerhut | It's not as featureful as things I've seen in other languages, but have you seen clojure.contrib.command-line/with-command-line? |
| 19:33 | andyfingerhut | i.e. Perl's GetOptions has lots more bells and whistles. |
| 21:19 | JAS415 | welp |
| 21:19 | JAS415 | eventually i'll know java well enough to use clojure properly :-P |
| 23:34 | Chouser | I knew chunked map would be hard, but I thought doseq might be pretty easy. |
| 23:35 | Chouser | now I'm not so sure. |