2009-09-15
| 03:07 | Fossi | hi |
| 03:08 | harblcat | hiya |
| 03:19 | LauJensen | Good morning gents |
| 03:23 | arbscht_ | hello |
| 05:39 | ChrisPS | Lisp without parentheses? |
| 05:42 | arbscht_ | ChrisPS: I don't understand |
| 05:42 | ChrisPS | There is an article at news.ycombinator.com |
| 05:42 | ChrisPS | something called Lispin |
| 05:43 | arbscht_ | hm, the linked page won't load for me. does it have anything to do with clojure? |
| 05:43 | ChrisPS | The site seems to be inaccessible right now, but there is google cache |
| 05:43 | ChrisPS | clojure is a lisp |
| 05:44 | ChrisPS | personally, I like the parentheses |
| 05:44 | ChrisPS | as it makes navigation easier, due to the sexp's |
| 05:48 | arbscht_ | this looks like every other futile attempt at eliminating parens from a lisp. I'm not sure what more can be said of it |
| 05:49 | arbscht_ | anyway, other lisps are generally off topic here. they tend to have their own channels :) |
| 05:49 | ChrisPS | I don't know, it doesn't really trouble me, sorry for the off-topic |
| 05:50 | arbscht_ | some folks tried inventing syntax for clojure that reduced the use of parens. iirc, that didn't stick |
| 06:05 | Chousuke | I like the second comment on the news item :) |
| 06:06 | Chousuke | just change the colour to match the background and the parens disappear :P |
| 06:06 | arbscht_ | heh |
| 06:19 | adityo | good afternoon folks |
| 06:20 | adityo | how would i write this in clojure new QName("http://apache.org/hello_world_soap_http", "SOAPService"); |
| 06:22 | adityo | got it :) |
| 06:22 | jdz | (new QName "http://..." "SOAPService")? |
| 06:34 | liwp | or (QName. "http://..." "SOAPServervice") |
| 06:34 | liwp | if I could spell, that is |
| 06:34 | powr-toc | Hey... I need to extend a java class in Clojure and set an instance variable within the super class... How do you do this? |
| 06:35 | AWizzArd | Which lib would you use for reading pdf files? |
| 06:37 | AWizzArd | jdz: do you prefer calling (new SomeClass ...) over (SomeClass. ...)? |
| 06:37 | clojurebot | new Class(x) is (Class. x) |
| 06:37 | jdz | i usually use new |
| 06:37 | jdz | but simetimes, when using -> macro, it's convenient to use the dotted syntax |
| 06:38 | liwp | IIRC the current favourite / idiomatic style is (Class. x) |
| 06:38 | jdz | well, the dot is easy to miss you know |
| 06:38 | liwp | yeah, I agree |
| 06:38 | liwp | I tend to forget to write it when I'm creating objects, i.e. I write (Class x) and then the compiler is angry at me |
| 06:42 | liwp | ,(String. "foo") |
| 06:42 | clojurebot | "foo" |
| 06:48 | powr-toc | still can't find any mention of setting protected member variables in super classes you extend with either proxy or gen-class |
| 06:48 | powr-toc | does anyone know if this is possible? |
| 06:48 | liwp | powr-toc: I haven't used proxy myself do I don't know. I think it's been asked on the mailing list a few times so it might be worth searching through the archives |
| 06:49 | liwp | also, the was some trick in searching the group... someting like "use the top level group search and pass in your search term and the group name" |
| 06:56 | powr-toc | liwp: hmmm still can't find anything :-( |
| 06:57 | powr-toc | I would have thought you'd be able to access/set member variables in a binding form or something |
| 07:08 | LauJensen | When I do (range 1000), is 0 calculated? Or is the head also lazy ? |
| 07:10 | liwp | ,(let [xs (map println (range 10))] 1) |
| 07:10 | clojurebot | 1 |
| 07:10 | liwp | seems to be lazy |
| 07:10 | liwp | ,(let [xs (map println (range 10))] xs) |
| 07:10 | clojurebot | (nil nil nil nil nil nil nil nil nil nil) |
| 07:10 | liwp | or then I did something silly... |
| 07:11 | liwp | ,(doall (let [xs (map println (range 10))] 1)) |
| 07:11 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer |
| 07:11 | liwp | ,(doall (let [xs (map println (range 10))] xs)) |
| 07:11 | clojurebot | (nil nil nil nil nil nil nil nil nil nil) |
| 07:11 | clojurebot | 0 1 2 3 4 5 6 7 8 9 |
| 07:12 | liwp | ,(let [xs (map println (range 10))] xs 1) |
| 07:12 | clojurebot | 1 |
| 07:12 | liwp | ,(let [xs (map println (range 10))] (doall xs) 1) |
| 07:12 | clojurebot | 1 |
| 07:12 | clojurebot | 0 1 2 3 4 5 6 7 8 9 |
| 07:13 | LauJensen | Thanks, I reached the same conclusion |
| 07:14 | liwp | IIRC that was the goal of Rich's fully lazy sequences that happened some time ago |
| 07:14 | liwp | I.e. in the past head was eager |
| 07:15 | liwp | but I might be wrong |
| 07:16 | LauJensen | No thats exactly how I remembered it also |
| 08:10 | weissj | If I have a list of lists, and i want to create a map where the keys are the 1st item in the inner lists, and the values are the inner list, how do i do that in a functional way? ie ((:a 1 2 3) (:b 2 3 4)) -> {:a (:a 1 2 3), :b (:b 2 3 4)} |
| 08:10 | dabd | hi, is it possible to use Jersey from clojure? |
| 08:11 | dabd | I am writing a bunch of RESTful web services using Jersey and I hate Java... |
| 08:11 | jdz | if Jersey is Java, then you can use it, yes |
| 08:12 | jdz | *is in |
| 08:13 | fullets | weissj: (into {} (map (fn [x] [(first x) x]) [[:a 1 2 3] [:b 2 3 4]])) |
| 08:13 | dabd | Jersey is Java but it relies heavily on annotations and it is not obvious for me how to use it from clojure |
| 08:14 | dabd | say in Jerse |
| 08:14 | weissj | fullets: ah, so simple :) thanks |
| 08:14 | dabd | y you define an annotated class and several methods how can you do it from clojure? |
| 08:14 | weissj | was trying to figure out how to add 2 items at a time, "into" is what does it |
| 08:15 | Fossi | weissj: should be possible with zipmap as well |
| 08:16 | Fossi | don't know which would be nicer |
| 08:16 | Fossi | depends on your usecase i guess |
| 08:17 | fullets | Fossi: that's much nicer, imo at least |
| 08:17 | fullets | (zipmap (map first blah) blah) |
| 08:18 | liwp | dabd: AFAIK clojure does not support annotations at the moment, so I think you're out of luck unless there is some other way to plug into Jersey |
| 08:18 | Fossi | sounds like jersey and clojure wouldn't be such a nice match |
| 08:19 | dabd | liwp: okay that's the impression I got from skimming through the Java Interop section of the manual: that it is not possible to define annotations |
| 08:21 | liwp | ,(let [xs [[:a 1 2 3] [:b 4 5 6]]] #(zipmap (map first %) %)) |
| 08:21 | clojurebot | #<sandbox$eval__2969$fn__2971 sandbox$eval__2969$fn__2971@f67d81> |
| 08:21 | liwp | ,(let [xs [[:a 1 2 3] [:b 4 5 6]]] (#(zipmap (map first %) %) xs)) |
| 08:21 | clojurebot | {:b [:b 4 5 6], :a [:a 1 2 3]} |
| 08:21 | liwp | that's not very nice at all actually... |
| 08:22 | liwp | I was trying to get away from repeating xs in the map and zipmap |
| 08:22 | dabd | maybe Java annotations could be implemented through clojure metadata |
| 08:22 | liwp | yeah, that would be the way to do it |
| 08:23 | liwp | in the end you need to change the compiler to add the annoations to the class file and AFAIK people don't really want to touch the compiler ;) |
| 08:31 | Mortah | I hear you guys are a friendly bunch, good work :D |
| 08:38 | dabd | liwp: an alternative would be to change gen-class so it generates annotated classes and methods |
| 08:39 | liwp | dabd: gen-calls doesn't go via the clojure compiler? |
| 08:39 | dabd | liwp: yes it does sorry |
| 08:40 | liwp | dabd: I'm sure annotations will get added at some point, but so far there hasn't been a lot of demand AFAICT |
| 08:41 | Chouser | I don't know much about annotations or rhickey's plans for dealing with them, but gen-class is Clojure's big hammer for cruddy Java interop where named classes are required -- it seems the natural place to add annotation support, if any, and nobody would have to touch the compiler. |
| 08:41 | Chouser | I just rewrote a small .clj file yesterday into a small .java file to support junit 4 annotations. |
| 08:41 | Chouser | As it turns out, Clojure wasn't buying me much there. |
| 08:42 | Jomyoot | Is Conjure or Compojure more promising? |
| 08:43 | liwp | Chouser: so is new new going to make gen-class obsolete? |
| 08:43 | Fossi | Jomyoot: i guess that depends what you are used to |
| 08:43 | Jomyoot | I am used to rails |
| 08:43 | Chouser | liwp: not at all |
| 08:43 | Jomyoot | But I am wondering which one will have more users |
| 08:44 | Jomyoot | want to use something that will have more active users |
| 08:44 | Fossi | Jomyoot: don't know. compojure works nicely for us as kind of a cl-who clone |
| 08:44 | Jomyoot | have you looked at conjure? |
| 08:45 | Fossi | and even if it doesn't attract a lot of users, it's pretty much feature complete because it's so simple |
| 08:45 | dabd | Chouser: if you end up using gen-class to write Java code with lisp syntax you might as well use Java directly |
| 08:45 | Chouser | new new (a.k.a. reify) is a native Clojure structure that will fully supported on other hosts (C#, JavaScript, etc.) |
| 08:46 | Chouser | in other words, not primarily a Java interop structure. gen-class and proxy are meant more for interop with Java libs that have unfortunate designs. |
| 08:46 | liwp | Chouser: ok |
| 08:48 | liwp | Chouser: is this correct, new new allow you to extend an existing class whereas gen-class is used to define a new class which optionally extends an existing class? |
| 08:51 | Chouser | liwp: yes, that's one of the differences. There are several. |
| 08:51 | Chouser | back in a minute. |
| 08:52 | Chousuke | liwp: I think everyone would prefer if you only implemented interfaces rather than extending existing classes (unless abstract) :) |
| 08:56 | liwp | Chousuke: if you don't want me to extend your classes / methods, you should declare them as final :) |
| 08:57 | weissj | If i have a list of items and i want a list with the nth item removed, how do i do that |
| 08:57 | weissj | do i have to use filter (or remove)? |
| 09:01 | Chousuke | liwp: the problem is even having classes that others might want to extend ;) |
| 09:01 | liwp | Chousuke: you mean in Clojure or in OO languages? |
| 09:02 | Chousuke | I suppose it depends a bit on the language |
| 09:03 | Chouser | weissj: neither vectors nor lists support efficiently removing an item in the middle, so yes you'll end up having to an O(n) walk |
| 09:04 | weissj | Chouser: ok thanks |
| 09:04 | Chouser | weissj: probably most efficient to use a vector, two subvecs, and conj them. |
| 09:06 | weissj | Chouser: yeah, all my vectors are 4 items long, and i just want to remove the 2nd item, so i can conj the first with a call to drop |
| 09:06 | Chouser | oh! actually, destructuring might be nice if they're that small. |
| 09:06 | Chouser | (let [[a _ b c] v] [a b c]) |
| 09:07 | weissj | Chouser: ok, i will try that, thanks! |
| 09:08 | liwp | Chouser: have you seen Guy Steele's talk at ICFP'09? http://research.sun.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf |
| 09:09 | liwp | he talks about concurrency friendly data structures, i.e. representing things like lists as trees so that you can parallelise operations on them |
| 09:09 | liwp | he introduces first conc lists (concatenation lists) and then talks about finger trees later on |
| 09:10 | Chouser | yes, I've looked through that. Clojure's vectors are actually trees internally |
| 09:10 | liwp | yep |
| 09:10 | liwp | I was just wondering if you can do all of that with just finger trees, i.e. if you have finger trees is there any use in conc lists |
| 09:10 | Chouser | so rhickey wrote some parallel ops to work on the vectors. |
| 09:10 | liwp | ahh, I haven't see those |
| 09:11 | liwp | is that what's in clojure.parallel? |
| 09:11 | Chouser | I never use them, so I don't remember. looking now. |
| 09:12 | Chouser | I think clojure.parallel is still using the forkjoin.ParallelArray, so that's not it. |
| 09:12 | liwp | ok |
| 09:12 | liwp | the docs talk about creating a parallel array from a collection, so it must be something else then the standard vector |
| 09:13 | Chouser | as, there's a 'par' branch |
| 09:13 | Chouser | "added clojure.par ns with pvmap and pvreduce" |
| 09:13 | liwp | cool |
| 09:14 | Chouser | so those work on regular clojure vectors, leveraging the tree structure. |
| 09:15 | liwp | I guess the 32 object fanout helps in avoiding splitting up the work too thinly |
| 09:15 | Chouser | yep. |
| 09:16 | Chouser | as for finger trees, I guess I don't know the theory well enough yet. They should be able to useful for doing all the things described in those slides. |
| 09:16 | Chouser | concat is efficient, etc. |
| 09:17 | liwp | that's what I'd expect, but the slides did not really state it explicitly and I don't know finger trees well enough to work it out for myself (the paper is at home on the TODO pile) |
| 09:17 | Chouser | cached monoids are used heavily in finger trees |
| 09:18 | liwp | there's a nice blog post about finger trees in haskell which explains with a few examples how the functionality changes when the monoid is changed |
| 09:18 | liwp | really cool |
| 09:19 | Chouser | my finger trees support Clojure's seq abstraction (ISeq) directly. That is, calling 'rest' on a finger tree gives you a new finger tree, amortized O(1) time. |
| 09:19 | liwp | http://apfelmus.nfshost.com/monoid-fingertree.html |
| 09:21 | Chouser | looks like there are slightly different performance profiles between finger trees and conc lists. Like first is O(1) for ft, appears to be avg O(log n) for conc, vs. concat O(log n) for ft and O(1) for conc |
| 09:22 | liwp | heh, now that you mention it, it seems obvious :) |
| 09:23 | Chouser | really? nothing about ft's have been obvious to me. :-P thought I think I'm starting to get a sense of how they really work now. |
| 09:23 | liwp | and rest is O(log n) for conc as well, right? Only concat is O(1) |
| 09:24 | Chouser | I think so, though in practice I'm not sure how it will always turn out. |
| 09:24 | liwp | Chouser: the conc list bit was the obvious bit, i.e. concat is O(1) and first is O(log n) |
| 09:25 | Chouser | That is, ft rest is slightly worse that O(1) and it uses delay to make it as good as possible. conc rest speed will depend on how the list was built I think (depth of left path may be short) |
| 09:25 | liwp | Chouser: I guess if you have an unbalanced conc list, then you might effectiely have a linked list and rest would be O(1) again |
| 09:25 | Chouser | right |
| 09:25 | liwp | Steele conveniently left out the balancing of conc lists from the slides |
| 09:25 | Chouser | heh |
| 09:26 | liwp | what do you do with fingertrees? do you need to rebalance? |
| 09:26 | Chouser | yeah, that's a nice feature of ft -- no rebalancing |
| 09:26 | liwp | ok |
| 09:26 | liwp | does that lead to pathological cases? |
| 09:27 | Chouser | I don't know. I wouldn't be surprised if the worst cases were O(log n) when you were hoping for amoritized O(1). But maybe it's not even that bad, not sure. |
| 09:27 | ankou | does clojure not even show line numbers or file at syntaxerrors like "unmatched parentheses" or is it a problem with slime? |
| 09:28 | liwp | ankou: I think it's a slime issue - I've only ever used slime myself |
| 09:29 | liwp | I also use paredit mode so it's hard to miss parens |
| 09:30 | ankou | I get an Message of an Exception with a backtrace of the reader but no line number of the error itself is included in the exceptionmessage |
| 09:30 | liwp | ankou: yep, that's quite common with clojure error messages |
| 09:30 | ankou | really annoying :\ |
| 09:30 | liwp | ankou: have a look at the stack trace, if that's available, usually there's a clue there |
| 09:31 | liwp | i.e. one or more stack frames mention your source file and line number |
| 09:31 | Chouser | I get: java.lang.Exception: Unmatched delimiter: ) (<file name>:<line number)) |
| 09:31 | liwp | slime won't even inject the code with a missing paren for me... |
| 09:32 | liwp | ahh, never mind - my test app killed my JVM... |
| 09:32 | liwp | it's very annoying when people bind the Swing close app button to System/exit... |
| 09:34 | ankou | Chouser: the same thing just without the extra information. I could find the file with the help of the stack trace however loading this file directly didn't give me more information |
| 09:51 | liwp | do people use a user.clj file in their classpath? |
| 09:52 | liwp | and if so, what's in it? |
| 09:53 | Chouser | I don't. My startup script puts -i $HOME/.clojure/repl-init.clj on the java command line |
| 09:54 | lisppaste8 | Chouser pasted "repl-init.clj" at http://paste.lisp.org/display/87096 |
| 09:54 | liwp | Chouser: do you use slime? |
| 09:54 | Chouser | no |
| 09:54 | liwp | are you using the raw repl or one of the IDE plugins? |
| 09:55 | Chouser | rlwrap + repl in a terminal |
| 10:03 | weissj | ok i should know this but how to turn a seq of strings into a concat'd string |
| 10:03 | weissj | (str (interpose "," '["a" "b"])) |
| 10:03 | weissj | "clojure.lang.LazySeq@1e636" |
| 10:04 | Chouser | apply |
| 10:04 | weissj | Chouser thx |
| 10:53 | Fossi | weissj: for that case there's str-join as well |
| 10:53 | Fossi | in contrib |
| 10:54 | Chouser | also contrib str-utils2/join |
| 11:08 | weissj | Fossi: yeah i think that was the one i was thinking of thanks |
| 11:09 | avital | what is used here for pasting code? |
| 11:10 | crios | http://paste.lisp.org |
| 11:11 | avital | ok cool so i was trying to use map on a hash map and since hash maps are collections as pairs the return value is not a hash map but rather a sequence of pairs |
| 11:11 | avital | so i wrote this instead |
| 11:11 | avital | http://paste.lisp.org/display/87103 |
| 11:11 | avital | is there any better way to map a hashmap? |
| 11:12 | avital | in my implementation map-map receives a function and a map, the function gets two arguments (key and value) and returns a sequence of length 2 containing the new key and value |
| 11:12 | Fossi | (map (fn [k v] (println k v)) {:a 1 :b 2}) |
| 11:12 | Fossi | ,(map (fn [k v] (println k v)) {:a 1 :b 2}) |
| 11:12 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--2982$fn |
| 11:13 | Fossi | ups |
| 11:13 | Fossi | ,(map (fn [[k v]] (println k v)) {:a 1 :b 2}) |
| 11:13 | clojurebot | (nil nil) |
| 11:13 | Chouser | ,(into {} (for [[k v] {1 1, 2 2}] [(* 2 k) (* 3 v)])) |
| 11:13 | clojurebot | {4 6, 2 3} |
| 11:13 | avital | that might work but if you actually want a return value from map it won't end up a hash map. |
| 11:13 | avital | oh what |
| 11:13 | avital | wait |
| 11:13 | avital | what |
| 11:13 | avital | what is into?! |
| 11:13 | Fossi | yeah, into then |
| 11:15 | Chouser | (into target source) is (reduce conj target source), only faster |
| 11:16 | avital | wow amazing |
| 11:16 | avital | ok |
| 11:16 | avital | thanks |
| 11:17 | Chouser | ankou: you're not the first to write map-map, but with into, for, zipmap, etc. I'm not sure people need map-map. |
| 11:18 | avital | Chouser: Not sure what you mean by "people need". If anyone feels that it makes his/her code simpler, more intuitive, etc. let them do it. |
| 11:18 | Chouser | oh sorry, mis-directed post there. |
| 11:19 | avital | My intuition says: If you can run map on maps, it should return a map. If not, then either it needs to be replaced or map-map should be part of clojure |
| 11:21 | Chouser | 'map' is always consumes a seq lazily, returning a lazy seq. Having it return a map or vector would be a poor fit, I think -- that's exactly what 'into' is for, pouring a (possibly lazy) seq into a strict collection. |
| 11:22 | Chouser | as for a separate map-map: http://google.com/search?q=clojure+"defn+map-map" |
| 11:23 | Chouser | hm, some of those "map-map"s do different things. |
| 11:24 | Jomyoot | How can you quickly convert from Java HashMap to Clojure Hash? |
| 11:25 | Chouser | Jomyoot: you need it to actually be persistent? |
| 11:25 | Jomyoot | not really |
| 11:25 | Jomyoot | either way is fine |
| 11:25 | Chouser | Jomyoot: clojure maps implement java map, so you may be able to just use it directly |
| 11:26 | Chouser | ,,(into {} (java.util.HashMap. {:a 1, :b 2, :c 3})) |
| 11:26 | clojurebot | {:a 1, :b 2, :c 3} |
| 11:26 | Jomyoot | cool |
| 11:26 | Chouser | there's a clojure map to a java map and back again. :-) |
| 11:27 | Jomyoot | What about a templated HashMap |
| 11:27 | Chouser | Jomyoot: doesn't matter |
| 11:28 | Chouser | Java generics are just a java compile-time check -- after the .java's been compiled, the collections don't care about their template params anymore |
| 11:52 | lisppaste8 | raphinou pasted "untitled" at http://paste.lisp.org/display/87104 |
| 11:53 | raphinou_ | here's a little paste about a question about the (defn my-func [args & more] ...) way of defining a function and handling the more var |
| 11:54 | raphinou_ | if second arg passed is a list, i would like more to be equal to that list. And I'm not sure what's the best way to do that... |
| 11:54 | Chousuke | I don't think that's a good idea :/ |
| 11:54 | Chousuke | anyone who wants the second argument to be a list can use apply anyway |
| 11:55 | Chousuke | I guess you could overload it for two arguments to check whether the second argument is a list or not. |
| 11:56 | Chousuke | eg (fn foo ([x y] (if (seq? y) (concat x y) (concat x [y]))) ([x & more] (concat l more))) |
| 11:57 | Chousuke | oops |
| 11:57 | Chousuke | the l should of course be x :P |
| 11:58 | Chousuke | or hmm |
| 11:58 | Chouser | ,(fn foo ([x y]) ([x & xs])) |
| 11:58 | clojurebot | java.lang.Exception: Can't have fixed arity function with more params than variadic function |
| 11:58 | Chousuke | oh damn |
| 11:58 | Chousuke | (defn foo [x & more] (concat x (flatten more))) |
| 11:58 | raphinou_ | chousuke: I agree it's not a good approach, but it's a question that popped up when wrtiting a test for such a function. To save time I put the more to be passed to the function, which is also the expected result , in a "variable" I could reuse |
| 11:59 | Chouser | don't use 'more', it's a builtin |
| 12:00 | raphinou_ | Chousuke: ha, I didn't know that! |
| 12:01 | Chousuke | Chouser: wait, more is? |
| 12:01 | Chousuke | (doc more= |
| 12:01 | clojurebot | EOF while reading |
| 12:01 | Chousuke | (doc more) |
| 12:01 | clojurebot | No entiendo |
| 12:01 | Chouser | Chousuke: oh, nope. sorry. that's the name of the method 'rest' calls. |
| 12:01 | Chousuke | heh. confusing :P |
| 12:02 | Chouser | yeah. there are a couple interface methods that kept early names. |
| 12:02 | Chouser | 'conj' calls 'foo.cons()' and 'rest' calls 'foo.more()' |
| 12:03 | raphinou_ | ok! |
| 12:03 | Chouser | rhickey: good luck! |
| 12:03 | rhickey | thanks! |
| 12:04 | raphinou_ | off to microsoft? for clojure? |
| 12:04 | Chouser | yeah, he's speaking |
| 12:05 | raphinou_ | he, cool |
| 12:06 | Chouser | raphinou_: anyway, you're sure you can't just use apply? it's the correct solution, and usually convenient. |
| 12:06 | raphinou_ | Chousuke: looking further at it |
| 12:07 | raphinou_ | Chousuke: actually, first trying to get the test pass with the "& others" arguments ;) |
| 12:07 | Sir_Diddymus | Hi all... I've extended a Java class (with :gen-class and :extends) and all is fine and works like expected. Now I need to call a protected final method of the superclass (from inside my extended class) - is there really no way do this? Or did I just not find it how to achieve this? |
| 12:08 | Chouser | raphinou_: otherwise, I don't think you can do better than (defn foo [x & xs] (let [xs (if (coll? (first xs)) (first xs) xs)] [x xs])) |
| 12:09 | Chouser | Sir_Diddymus: did you look at :exposes-methods ? |
| 12:11 | Sir_Diddymus | Chouser: yup... but maybe I didn't use it correctly. And I thought I can only access overridden methods of the superclass that way? At least that is what the API docs specify... |
| 12:12 | Sir_Diddymus | Chouser: and well, since the protected method is final, no override possible... :\ |
| 12:13 | Chouser | I think that's a red herring. ignore the stated purpose and look at what it does. |
| 12:13 | Chouser | I *think* it'll work for you. |
| 12:14 | Sir_Diddymus | hmm... k... than I probably just did something wrong. I thought I tried that... |
| 12:14 | Chouser | :exposes-methods creates new public methods that can call protected methods of the superclass |
| 12:14 | Chouser | yeah, gen-class is a bit tricky to use right. :-/ |
| 12:15 | Sir_Diddymus | yup. probably wrong syntax or something. |
| 12:19 | Chousuke | aa |
| 12:19 | Chousuke | oops. |
| 12:24 | Sir_Diddymus | nope, still doesn't work. :( |
| 12:24 | Chouser | lisppaste8: url? |
| 12:24 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 12:24 | Chouser | Sir_Diddymus: shows us what you've tried? |
| 12:25 | Sir_Diddymus | k... sec... |
| 12:30 | lisppaste8 | Sir_Diddymus pasted "calling a protected final method?" at http://paste.lisp.org/display/87106 |
| 12:32 | lowlycoder | is there any reason to use clojure from git instead of the latest stable? |
| 12:32 | Chouser | Sir_Diddymus: what error do you get? |
| 12:33 | Sir_Diddymus | This is the signature of the method: protected final void beginInsertRows(com.trolltech.qt.core.QModelIndex parent, int first, int last) |
| 12:33 | Sir_Diddymus | This is the error: |
| 12:34 | Sir_Diddymus | java.lang.IllegalArgumentException: No matching method found: beginInsertRowsSuper for class name.space.XStoreListModel |
| 12:36 | Chouser | Sir_Diddymus: do you have repl-utils from contrib? |
| 12:36 | Sir_Diddymus | Somehow I can't believe that it shouldn't be possible. Would be a real bummer though, if it really didn't work. |
| 12:36 | Sir_Diddymus | yeah, i think so... |
| 12:36 | Chouser | try (show name.space.XStoreListModel) |
| 12:36 | Sir_Diddymus | after loading the class? |
| 12:37 | Chouser | sure, or just have compiling it. |
| 12:38 | Chouser | that should list all the defined methods. |
| 12:39 | Chouser | and should allow you to see if beginInsertRowsSuper is generated at all, or if it's the arg types causing problems. |
| 12:42 | stuartsierra | ~seen dysinger |
| 12:42 | clojurebot | dysinger was last seen quiting IRC, 790 minutes ago |
| 12:42 | Sir_Diddymus | nope... no begin* method found. |
| 12:43 | Sir_Diddymus | ok, compiled it again to be sure, but not listed. |
| 12:46 | Sir_Diddymus | I thought that I read somewhere that the combination "protected final" is the problem. But that would practically mean, that frameworks like Qt aren't (fully) usable. |
| 12:55 | icylisper | how to get a list of all functions defined in a given namespace ? |
| 12:57 | tmountain | icylisper: ns-map ? |
| 12:58 | icylisper | ah thanks. will check |
| 12:58 | tmountain | np |
| 13:00 | icylisper | um-, dont see how i can filter the defns. |
| 13:03 | tmountain | looks like ns-interns is actually better for what you want |
| 13:03 | icylisper | or maybe ns-publics |
| 13:03 | tmountain | user=> (ns foo) |
| 13:03 | icylisper | thanks :) |
| 13:04 | tmountain | foo=> (defn sum [a b] (+ a b)) |
| 13:04 | tmountain | user=> (ns-interns 'foo) |
| 13:04 | tmountain | {sum #'foo/sum} |
| 13:04 | tmountain | np, I'm figuring this out as I go, so I'm wrong a lot ;-) |
| 13:04 | Chousuke | icylisper: (filter (fn [[k v]] (fn? v)) (ns-interns 'whatever)) |
| 13:04 | tmountain | yeah, that looks good |
| 13:04 | Chousuke | oh but wait |
| 13:04 | Chousuke | it's vars |
| 13:05 | Chousuke | you need (deref v) |
| 13:05 | icylisper | ah. |
| 13:05 | Chousuke | (or @v :P) |
| 13:05 | icylisper | cool. thanks Chousuke. |
| 14:02 | crios | clojurebot: logs? |
| 14:02 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 14:17 | crios | sir_diddymus, your problem can be related to the ticket http://www.assembla.com/spaces/clojure/tickets/126-abstract-superclass-with-non-public-accessibility ? |
| 14:18 | Sir_Diddymus | crios: thanks, taking a look... |
| 14:20 | crios | check this also: http://groups.google.com/group/clojure/browse_thread/thread/d1fbdb7450b46dee/b5539e4a21c411c6?pli=1 |
| 14:20 | crios | unluckly I'm too much newbe on Clojure , to be of any help to you :) |
| 14:24 | Sir_Diddymus | hm... I'm not really sure if both of them apply, since I have a derived class and inside of that, I'm trying to call a protected final method of the superclass. I can call public methods from the abstract superclass just fine. |
| 14:24 | Chouser | that second link is solved with :post-init |
| 14:25 | Chouser | the first I don't think applies |
| 14:25 | Sir_Diddymus | Well, to be correct, the public method I can call are in the abstract base class, as well as the superclass... |
| 14:25 | Chouser | I've got a stand-alone example that reproduces the problem. |
| 14:25 | Sir_Diddymus | s/method/methods/ |
| 14:28 | crios_ | this patch? http://code.google.com/p/clojure/issues/detail?id=45 |
| 14:28 | Chouser | maybe something's wrong with my .java |
| 14:28 | Chouser | oh. duh... |
| 14:28 | Chouser | crios_: yes |
| 14:29 | crios_ | 'this' and 'super' Java keywords cannot be used into Clojure interop. code? |
| 14:30 | Chouser | 'this' and 'super' are not special words in clojure (expcept for 'this' inside 'proxy' forms) |
| 14:31 | Sir_Diddymus | crios_: when extending a class, the first parameter in the methods (overridden as well as :exposed) get set to "this", you can call it however you want, as far as I know... |
| 14:31 | Chouser | Sir_Diddymus: maybe I've just misunderstood gen-class and mislead you. Maybe exposes-methods just doesn't work on protected methods. |
| 14:32 | Sir_Diddymus | Chouser: yeah, that's what a gathered from reading the API docs. And by trying. ;) |
| 14:33 | lisppaste8 | Chouser annotated #87106 ":exposes-methods not for protected?" at http://paste.lisp.org/display/87106#1 |
| 14:33 | Chouser | time to check the code. |
| 14:34 | Chouser | if not past time :-/ |
| 14:40 | crios | if i well remember, protected methods can be accessed just by subclasses. How clojure "proxy" the classes? by delegation? |
| 14:41 | crios | i mean, when you compile myns.pityme you get a its proxied subclass? |
| 14:41 | crios | or a clojure object which delegates to myns.pityme? |
| 14:42 | Chouser | gen-class produces a subclass with a bunch of methods. Each method listed in :methods or defined as public by a superclass, you get a little method that delegates to a defn in the given namespace. |
| 14:43 | Chouser | but you can use :init, :post-init, :exposes, and :exposes-methods to generate more methods that don't deletgate to defns in the same way, but hook other code directly into the generated class. |
| 14:43 | crios | ok |
| 14:44 | Chouser | ok, from the code, gen-class only considers for :expose-methods methods that are "non-private" |
| 14:46 | Chouser | it specifically excludes methods that are named "finalize" or are final. |
| 14:47 | Chouser | (or a few other things) |
| 14:47 | Chouser | I wonder if that clause for excluding final methods really makes sense for :exposes-methods. |
| 14:48 | crios | finalize? |
| 14:49 | crios | maybe when clojure exposes that methods with expose-methods, would give you a chance to "override" them? |
| 14:50 | crios | a sort of overriding, i mean |
| 14:50 | Chouser | well that's the thing -- you're not overriding a final method, just providing a way to call it. |
| 14:51 | Chouser | this list of non-private methods is used for a few other things -- I wonder if 'final' is good to exclude from those, but not :expose-methods |
| 14:53 | Chouser | oh, it's a Range. Not sure what that is. |
| 14:54 | Chouser | sorry, wrong window. |
| 15:11 | Sir_Diddymus | so :exposes-methods is definitely not the way to go. But shouldn't I be able to just use the method, since protected methods are accessible to subclasses in Java world? Hm... |
| 15:12 | Chouser | your clojure fn is not *in* the subclass, it's called by the subclass. |
| 15:12 | Chouser | with reify you could call it directly |
| 15:13 | Chouser | I think your best bet for now would be to write a subclass in .java that has a public method that calls the protected one, and then subclass that (using either proxy or gen-class) |
| 15:14 | Chouser | and/or bring it up on the group and see if others have solved this problem. I wouldn't be surprised if this leads to a tweak of :exposes-methods |
| 15:15 | Chouser | no matter how much rhickey hates protected methods, they won't just go away. :-) |
| 15:16 | Sir_Diddymus | ugh... not pretty. ;) Yeah, that's what I wondered. I mean ok, it's Java and not all to lispy, but then again this should crop up more than once - especially with GUI frameworks. |
| 15:17 | Sir_Diddymus | already wrote a message to the group... |
| 15:18 | Sir_Diddymus | anyway, thanks for the help... |
| 16:18 | LauJensen | Gentlemen, I hope you enjoy the read: http://www.dzone.com/links/scala_vs_clojure_lets_get_down_to_business.html |
| 16:22 | triyo | LauJensen: link to the actual post doesn't seem to work |
| 16:23 | triyo | says "Looks like you have a problem here sir/madam...." |
| 16:23 | LauJensen | argh |
| 16:24 | Chousuke | why don't you just link directly to the blog post? :P |
| 16:24 | strlen | http://bestinclass.wordpress.com/ |
| 16:25 | strlen | that's where the post is |
| 16:26 | strlen | ugh that blog post is wrong |
| 16:26 | strlen | scala will do tail recursion |
| 16:26 | strlen | not TCO |
| 16:26 | LauJensen | strlen, try it, will bork at 3600! just like Clojure |
| 16:26 | strlen | and that isn't written in a way that it will do tail recursion |
| 16:27 | LauJensen | But anyway, the DZone link works, you just need a hard refresh |
| 16:27 | strlen | LauJensen: it can do a true tail recursion |
| 16:27 | Chouser | ah, I didn't catch that! |
| 16:27 | strlen | the way that code is written in scala though -- on that page |
| 16:27 | strlen | isn't tail recursion |
| 16:27 | strlen | one sec |
| 16:28 | strlen | clojure will do tail recursion using 'recur' |
| 16:28 | Chouser | strlen: you're right that TCO wouldn't fix that algorithm. |
| 16:28 | strlen | now you can't do true TCO |
| 16:28 | strlen | as in |
| 16:28 | strlen | it will only do tail *RECURSION* |
| 16:28 | strlen | not tail call optimization which is different as it works across functions |
| 16:30 | LauJensen | Oh okay, I didn't make that distinction |
| 16:30 | strlen | but both scala and clojure do tail recursion. clojure does it using 'recur' as clojure is dynamically typed (and there's no invokedynamic yet) |
| 16:30 | Chousuke | LauJensen: technically, Clojure doesn't have lazy evaluation. it only has lazy seqs. |
| 16:31 | Chousuke | function parameters and such are still strict |
| 16:31 | LauJensen | Chousuke: I know, #scala is going on the same thing right now |
| 16:31 | strlen | you can also do future objects in scala for lazy evals |
| 16:31 | strlen | both languages are fun that's what matters :-) |
| 16:31 | Chouser | the examples both demo the correct transformation from non-tail to tail recursive structure |
| 16:32 | strlen | http://www.bluishcoder.co.nz/2006/07/scala-futures-and-lazy-evaluation.html |
| 16:32 | strlen | woiw that's ancient blog post |
| 16:32 | strlen | http://www.scala-lang.org/node/49 |
| 16:33 | Chouser | 2006! Clojure didn't even exist |
| 16:56 | hiredman | it would be nice if range worked on characters |
| 16:57 | hiredman | ,(map char (range (int \a) (int \e))) |
| 16:57 | clojurebot | (\a \b \c \d) |
| 16:58 | Chouser | ,(+ \a 1) |
| 16:58 | clojurebot | java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number |
| 16:59 | Chouser | (range \a \e \u0001) ? |
| 17:00 | Chousuke | hmm. |
| 17:00 | Chouser | :-) |
| 17:00 | hiredman | sure |
| 17:00 | hiredman | I can understand (+ \a 1) not being valid, but (range \a \z) would be nice |
| 17:01 | Chousuke | ,(map char (range (int \か) (int \さ))); let's see what happens with non-ascii :P |
| 17:01 | clojurebot | (\か \が \き \ぎ \く \ぐ \け \げ \こ \ご) |
| 17:01 | Chousuke | ooh, it works. |
| 17:02 | Chousuke | though usually you wouldn't want the ones with the dots if you did that :) |
| 17:02 | Chouser | well, range calls + internally -- fix + and I think range would Just Work |
| 17:02 | Chousuke | it's kind of like getting aAbBcCdD... |
| 17:02 | hiredman | Chouser: or just split the code path |
| 17:04 | hiredman | (if (instance? x Character) (make-int-and-call-range x) ...) |
| 17:04 | hiredman | or something |
| 17:18 | LauJensen | Guys, feel free to drop a vote, I get the sense #scala isn't exactly going to help :) http://www.dzone.com/links/scala_vs_clojure_lets_get_down_to_business.html |
| 17:23 | Chouser | rhickey: landed? |
| 17:27 | LauJensen | Its been a good night on #scala |
| 17:27 | LauJensen | (23:27:34) mapreduce: LauJensen: I await part 3, Chuck Norris vs. Martin Odersky. |
| 17:27 | LauJensen | (23:28:06) LauJensen: "Chuck Norris doesn't do push ups - Rich Hickey won't let him" |
| 17:27 | LauJensen | I'll leave you with that, good night :) |
| 17:47 | dthomas | Before I write a quick little "walk nested maps [produced from JSON]" function, is there something already written that I should be using? I actually just need to get a sequence of map entries that match a given predicate, traversing the whole nest of maps. |
| 17:48 | Chousuke | does it have to preserve the structure? |
| 17:48 | Chousuke | if not, you could filter and flatten. |
| 17:48 | dthomas | I think no, not interested in the location of the matches within the tree. |
| 17:49 | dthomas | Ah, flatten. |
| 17:49 | Chousuke | (doc flatten) |
| 17:49 | clojurebot | "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil." |
| 17:49 | Chousuke | hm |
| 17:50 | Chousuke | no namespace still ;/ |
| 17:50 | Chousuke | c.c.seq-utils? :/ |
| 17:52 | dthomas | Yeah, found it. (flatten some-map) => () isn't what I was expecting. |
| 17:53 | dthomas | (Oh, (indexed), I wanted that the other day. Good to know it's there.) |
| 17:57 | Chousuke | hm |
| 17:57 | Chousuke | ,(flatten {:foo :bar :zonk {:a :b}}) |
| 17:57 | clojurebot | () |
| 17:58 | Chousuke | huh. |
| 17:58 | Chousuke | that has to be a bug :P |
| 17:58 | hiredman | Chousuke: if the namespace has been use'ed in the sandbox namespace, then you don't get namespace information |
| 17:58 | Chousuke | ,(flatten (seq {:foo :bar :zonk {:a :b}})) |
| 17:58 | clojurebot | (:foo :bar :zonk {:a :b}) |
| 17:59 | hiredman | ~def flatten |
| 17:59 | Chousuke | dthomas: looks like you'll need your own function. take a look at tree-seq though. |
| 17:59 | hiredman | ,(doc sequential?) |
| 17:59 | clojurebot | "([coll]); Returns true if coll implements Sequential" |
| 17:59 | hiredman | ,(sequential? {}) |
| 17:59 | clojurebot | false |
| 17:59 | Chousuke | ,(doc tree-seq) |
| 17:59 | clojurebot | "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree." |
| 17:59 | hiredman | ^- |
| 18:00 | Chousuke | ,(tree-seq (comp map? val) seq {:foo :bar :foo {:a :b}}) |
| 18:00 | clojurebot | java.lang.ClassCastException |
| 18:00 | Chousuke | oops. |
| 18:01 | Chousuke | ,(tree-seq (comp val map?) seq {:foo :bar :zonk {:a :b}}) |
| 18:01 | clojurebot | java.lang.ClassCastException |
| 18:01 | dthomas | tree-seq, that looks promising. |
| 18:01 | Chousuke | ... okay I fail |
| 18:02 | mabes | can I coerce a vector into a a list of arguments? meaning.. if I have (def a [1 2 3]) and I want to call < on a so it would be (< 1 2 3), is that possible? |
| 18:02 | Chousuke | (apply < a) |
| 18:02 | mabes | Chouser: cool, thakns. just playing/learning clojure now- so sorry for the probably simple question :) |
| 18:04 | Chousuke | simple questions are fine |
| 18:04 | Chousuke | easy to answer so I can look like a wise sage or something :P |
| 18:09 | lisppaste8 | beutdeuce pasted "Efficiency question" at http://paste.lisp.org/display/87136 |
| 18:18 | Chousuke | beutdeuce: with reduce, * is a function call every time and you have a lazy seq too. in the explicit loop, there is no laziness involved and * can be inlined. |
| 18:18 | Chousuke | beutdeuce: is this git master or 1.0.0? |
| 18:19 | beutdeuce | 1.0 i believe |
| 18:19 | beutdeuce | not the 1.1.0 snapshot |
| 18:19 | beutdeuce | there are changes? |
| 18:19 | beutdeuce | *significant* changes? |
| 18:20 | Chousuke | yes. |
| 18:20 | Chousuke | :) |
| 18:20 | beutdeuce | :) for example? |
| 18:21 | Chousuke | some performance improvements for reduce et al via chunked seqs, transients, hmm... reify coming soon I guess. |
| 18:21 | Chousuke | enough that I have lost track of it all :P |
| 18:22 | beutdeuce | sounds exciting |
| 18:22 | beutdeuce | and it has been 2 years |
| 18:22 | hiredman | uh |
| 18:23 | hiredman | nope |
| 18:23 | Chousuke | 2 years since what? |
| 18:23 | hiredman | 1.0 was months ago (5?) |
| 18:23 | Chousuke | oh and then there's the JDK forkjoin library thing which seemed rather impressive. |
| 18:23 | Chousuke | JDK7* |
| 18:23 | beutdeuce | sweet! and ya, i forgot about 1.0 |
| 18:24 | beutdeuce | is jdk 7 even mainstream? |
| 18:24 | Chousuke | but, help. my emacs is no longer treating my option key as alt :( |
| 18:24 | Chousuke | beutdeuce: nope, but the library is already available as a separate download for 1.6 too :) |
| 18:26 | beutdeuce | i should try that out. I read in an article somewhere (i forgot) about the vm becoming very efficient and overpowering c++ in various different areas it used to drag behind in. |
| 18:27 | beutdeuce | is that sun java 7? or openjdk |
| 18:30 | beutdeuce | ,(reduce (fn [n acc] (println (* acc n))) (range 5)) |
| 18:30 | clojurebot | java.lang.NullPointerException |
| 18:30 | beutdeuce | ? |
| 18:31 | Chousuke | beutdeuce: I just tested |
| 18:31 | Chousuke | beutdeuce: on my computer the reduce version is actually faster. |
| 18:32 | hiredman | beutdeuce: println returns nil |
| 18:32 | Chousuke | but your loop is not optimised so that's not so surprising :) |
| 18:32 | beutdeuce | oh right |
| 18:32 | beutdeuce | how much faster? |
| 18:32 | Chousuke | not much |
| 18:32 | beutdeuce | faster than tail-recursion in that example? |
| 18:33 | Chousuke | about 30-40ms on average |
| 18:33 | Chousuke | but hm, let me see if I can optimise the loop and see what that does. |
| 18:33 | Chousuke | hahah |
| 18:34 | Chousuke | I got an integer overflow |
| 18:34 | Chousuke | figures |
| 18:34 | beutdeuce | :P |
| 18:34 | Chousuke | looks like there's no getting around using bignums |
| 18:34 | Chousuke | so reduce wins :P |
| 18:35 | beutdeuce | Reduce | Recur || 1 | 0 |
| 18:35 | beutdeuce | say, anyone know how to get rid of that annoying emacs auto-paranthesis match? |
| 18:36 | Chousuke | auto-parenthesis? |
| 18:36 | Chousuke | annoying? :) |
| 18:36 | beutdeuce | like, i cant close paranthesis until i delete whats between them |
| 18:36 | beutdeuce | it doesnt let me |
| 18:36 | Chousuke | you don't want to get rid of that |
| 18:36 | Chousuke | trust me |
| 18:37 | Chousuke | just learn to use paredit instead |
| 18:37 | beutdeuce | paredit? |
| 18:37 | Chousuke | it's what the thing is called |
| 18:37 | beutdeuce | k |
| 18:37 | beutdeuce | well |
| 18:37 | beutdeuce | its just that it glitched, so i had an open paran, but i couldnt delete it cause it said it was unmatched, i didnt see where the closing one was |
| 18:37 | Chousuke | it's "structured editing". it doesn't let you write s-exps that are "broken" |
| 18:38 | beutdeuce | better now, restarted emacs |
| 18:38 | Chousuke | if you really have an unmatched paren, do C-q ) |
| 18:38 | Chousuke | (C-q is "quote") |
| 18:38 | beutdeuce | k, thnx |
| 18:38 | Chousuke | anyway, paredit can do much more than just match your parens. |
| 18:39 | Chousuke | you can actually move around entire s-expressions. |
| 18:39 | Chousuke | without fear of breaking them. |
| 18:39 | beutdeuce | hmm, cool |
| 18:40 | Chousuke | the most common operations are barf and slurp: ctrl-leftarrow/rightarrow |
| 18:40 | Chousuke | and ctrl-k kills (cuts) a s-expression instead of a line |
| 18:40 | tomoj | arrows? blasphemy :P |
| 18:40 | Chousuke | tomoj: the real combo is something weird. |
| 18:41 | Chousuke | arrows are easier. |
| 18:41 | tomoj | C-(, C-), C-{, C-} |
| 18:42 | tomoj | I don't like having to reach all the way over to the arrow keys :/ |
| 18:42 | Chousuke | C-{ is impossible on my layout and C-( is nothing nice either. |
| 18:42 | tomoj | yeah |
| 18:42 | tomoj | programmer's dvorak here so those are really easy :) |
| 18:42 | mDuff | tomoj, ...hmm; how is that to learn coming from traditional dvorak? |
| 18:43 | tomoj | mDuff: not too bad |
| 18:43 | tomoj | I'm still not used to the numbers |
| 18:43 | beutdeuce | does println do *out* ? |
| 18:43 | Chousuke | beutdeuce: http://www.aaronfeng.com/articles/2008/03/23/barf-and-slurp-with-paredit |
| 18:44 | beutdeuce | nice |
| 18:44 | Chousuke | I don't think I'll be able to edit lisp code without that anymore ;( |
| 18:45 | tomoj | mDuff: I can't imagine at this point doing lisp (especially clojure, with its []s and {}s) with normal dvorak now |
| 18:58 | hlship | Question about getting patches, to clojure-contrib, accepted. |
| 18:58 | hlship | I attached a patch to ticket #24 about three weeks ago |
| 18:59 | hlship | I don't have commit access |
| 18:59 | hlship | who should I assign it to, to get the patch committed? |
| 18:59 | hlship | Or is there a special status? |
| 18:59 | hlship | http://www.assembla.com/spaces/clojure-contrib/tickets/24 |
| 19:47 | emacsen | Hey. I have a question. This page: http://www.geotools.org/quickstart.html#quickstart says that I need to set up a maven project for java inclusion. How would that work with a Clojure program? |
| 19:56 | interferon | is there a clojure function that might be called "group-by" which takes a sequence and returns a map that groups the elements of the sequence by a function? |
| 19:56 | hlship | sorry .. had to leave; any answer to my prior question about patches? |
| 19:58 | Potplant | interferon: sure is. clojure.contrib.seq-utils/group-by |
| 19:59 | _mst | ,(clojure.contrib.seq-utils/group-by #(mod % 5) (range 20)) |
| 19:59 | clojurebot | {0 [0 5 10 15], 1 [1 6 11 16], 2 [2 7 12 17], 3 [3 8 13 18], 4 [4 9 14 19]} |
| 20:02 | interferon | great! |
| 20:02 | interferon | thanks |
| 20:03 | interferon | and congratulations on parsing my mess of a sentence :) |
| 23:53 | danlarkin | wtb rich hickey :) |