2010-08-03
| 00:31 | notsonerdysunny | I was looking around for sexp like serialization this morning and found |
| 00:31 | notsonerdysunny | http://en.wikipedia.org/wiki/Canonical_S-expressions |
| 00:32 | notsonerdysunny | http://people.csail.mit.edu/rivest/sexp.html |
| 00:32 | notsonerdysunny | it would be nice to have clojure-based interface for it .. |
| 00:48 | notsonerdysunny | whats a good way to do clojure and java native stuff ? |
| 00:49 | qbg | JNI? |
| 00:50 | notsonerdysunny | yea I know there is JNI and JNA(supposedly newer stuff) .. but I also found a couple of clojure jn[ai] stuff on the clojars .. I was wondering if anybody had any input on which is a good one to use |
| 02:50 | slyrus | hrm... one of the differences between flet and labels in common lisp is that in the bodies of flet'ed functions, the function name isn't bound to the local function. is there a way to do similar in clojure? |
| 02:51 | slyrus | an enclosing let to squirrel away the old binding? |
| 02:51 | slyrus | works, but I don't suppose there's a more flet-y form I'm missing? |
| 02:55 | Chousuke | slyrus: can't you do just (let [foo (fn ...)] ...) |
| 02:56 | tomoj | slyrus: why does it matter? just curious, not saying it doesn't |
| 02:56 | slyrus | I sure can Chousuke, thanks! |
| 02:57 | slyrus | tomoj: if I want to locally rebind a function and be able to call the original function from the new function body, I can't using letfn. |
| 02:57 | tomoj | do you often want to do that? |
| 02:58 | tomoj | oh, I think I see |
| 02:58 | slyrus | (defn foo [x] (+ 17 x)) (let [foo (fn [x] (+ 33 (foo x)))] (foo 3)) |
| 02:58 | tomoj | right |
| 02:58 | slyrus | sure, I'm adding 33 and 17 to numbers all the time! |
| 02:58 | slyrus | :) |
| 02:58 | tomoj | just never wanted to shadow like that before |
| 02:58 | tomoj | but I think I can imagine situations where it would be useful |
| 02:59 | Chousuke | slyrus: I'd rather do (let [orig-foo foo] ...). Shadowing like that is pretty confusing |
| 02:59 | brehaut | would letfn be closer ? |
| 03:00 | slyrus | brehaut: letfn doesn't work as it would just recursively call foo |
| 03:00 | brehaut | oh right |
| 03:06 | slyrus | and my nasty little hack is foiled by the fact that I can't let a qualified name. oh well, it was probably a bad idea anyway. |
| 03:29 | raek | good morning |
| 03:30 | brehaut | hi raek |
| 03:43 | brehaut | paredit bindings in counterclockwise have made my day |
| 03:47 | esj | morning all |
| 04:04 | LauJensen | Good morning all |
| 04:05 | LauJensen | (incl. esj) |
| 04:05 | brehaut | evening |
| 04:11 | sid3k | morning guys |
| 04:12 | LauJensen | Morning sid3k :) |
| 04:14 | esj | yo |
| 04:14 | xkb | yoyo |
| 05:28 | cais2002 | how do I convert a str to a number ? |
| 05:31 | AWizzArd | cais2002: use the wrapper classes Integer, Long, Byte, etc. |
| 05:31 | AWizzArd | ,(Integer/parseInt "55") |
| 05:31 | clojurebot | 55 |
| 05:32 | cais2002 | -> (Integer. "55") |
| 05:32 | sexpbot | => 55 |
| 05:32 | cais2002 | is there a simpler way? |
| 05:32 | cais2002 | ,(str 55) |
| 05:32 | clojurebot | "55" |
| 05:32 | tomoj | there's (read-string "55"), but... |
| 05:33 | AWizzArd | this is less efficient, but if you are not in a tight loop it might be okay |
| 05:34 | tomoj | how exactly is (Integer. "55") complicated? |
| 05:34 | AWizzArd | cais2002: a pretty safe way for conversion is instantiating a BigDecimal, as this can eat all your numbers |
| 05:35 | cais2002 | tomoj: i thought there is some "native" function to do it |
| 05:35 | tomoj | java hater? :) |
| 05:35 | zmila | ,(type (load-string "1234")) |
| 05:35 | clojurebot | DENIED |
| 05:36 | zmila | ,(load-string "1234") |
| 05:36 | clojurebot | DENIED |
| 05:37 | tomoj | -> (class (read-string "1234")) |
| 05:37 | sexpbot | => java.lang.Integer |
| 05:37 | AWizzArd | load-string is about the most inefficient way to do this |
| 05:38 | tomoj | something like (read-string "{}") will work fine until you try to use it as a number, (Integer. "{}") will properly blow up |
| 05:38 | zmila | i supose so too :) but i think it's the way, when you don't know which datatype is there in the string |
| 05:38 | zmila | it's like (eval ) ? |
| 05:39 | AWizzArd | converting 10000 strings to a number via load-string: 400 msecs, read-string: 14 msecs, BigDecimal.: 5.8 msecs, Integer/parseInt: 3.6 msecs |
| 05:39 | tomoj | huh |
| 05:39 | tomoj | why does it take so long for a number to eval to itself? |
| 05:40 | tomoj | oh, load-string isn't (comp eval read-string) |
| 05:41 | AWizzArd | right |
| 05:42 | tomoj | .. (load-string "1.234 (launch-the-nukes)") |
| 05:42 | AWizzArd | Really, if it is an int, just call Integer. on it. |
| 05:44 | cais2002 | yeah, I will just use Integer/parseInt |
| 05:44 | zmila | and wrap into (catch NumberFormatExc) |
| 05:45 | cais2002 | ah yes |
| 06:26 | LauJensen | AWizzArd: Did you bench Integer. vs Integer/parseInt ? |
| 06:29 | LauJensen | ,(time (dotimes [_ 1e6] (Integer. "55"))) |
| 06:29 | clojurebot | "Elapsed time: 157.381 msecs" |
| 06:29 | LauJensen | ,(time (dotimes [_ 1e6] (Integer/parseInt "55"))) |
| 06:29 | clojurebot | "Elapsed time: 106.514 msecs" |
| 06:33 | tomoj | that's odd |
| 06:34 | bobo_ | LauJensen: hows the plans for next round of conj-labs going? saw something about trouble finding a venue? |
| 06:35 | LauJensen | bobo_: Germany has proven to be a challenge in terms of finding a good venue. We're teamed up with InnoQ who have been doing a lot of ground work, so I hope to be able to release a venue and date before long - hopefully no longer than 1 week from today |
| 06:35 | bobo_ | great! |
| 06:37 | LauJensen | Yea we're really putting in some work to ensure that it indeed becomes 'great' :) |
| 06:37 | bobo_ | :-) |
| 06:37 | esj | LauJensen: where is the content going to be aimed ? |
| 06:38 | LauJensen | esj: We'll aim it at the attendants :9 |
| 06:38 | LauJensen | What do you mean? |
| 06:38 | esj | hahahahah |
| 06:38 | esj | i mean are you giving 1). An introduction to Clojure, 2). An exploration of certain ideas in Clojure 3). Advanced concurrency coding etc etc ? |
| 06:39 | AWizzArd | LauJensen: yes, I tried Integer. vs. Integer/parseInt, and they are virtually equally efficient |
| 06:40 | LauJensen | Its a little early to say, but I think the level will not be as high as the Brussels session (which was über advanced), but it will be more catering to people looking to acquire the skills for professional use. Since we work 'lab style' we accomodate the individual attendants though, so everybody gets challenged (a little more than they hoped for) :) |
| 06:40 | tomoj | parseInt does seem to be reliably a little tiny bit faster to me, wonder why |
| 06:40 | LauJensen | AWizzArd: I always found parseInt to be about 30% faster |
| 06:41 | tomoj | I'm seeing more like 3% |
| 06:42 | AWizzArd | LauJensen: please try (time (dotimes [i 10000000] (Integer. (str i )))) |
| 06:42 | tomoj | it must be that new is slower than . ? |
| 06:43 | AWizzArd | and (time (dotimes [i 10000000] (Integer/parseInt (str i)))) |
| 06:43 | AWizzArd | ,(time (dotimes [i 100000] (Integer. (str i )))) |
| 06:43 | clojurebot | "Elapsed time: 58.767 msecs" |
| 06:43 | AWizzArd | ,(time (dotimes [i 100000] (Integer/parseInt (str i )))) |
| 06:43 | clojurebot | "Elapsed time: 58.959 msecs" |
| 06:44 | Bahman | Hi all! |
| 06:44 | LauJensen | Bahman: yo |
| 06:44 | Bahman | Hi there LauJensen! |
| 06:44 | tomoj | still ~3% faster it seems |
| 06:45 | LauJensen | Yea also a little faster locally |
| 06:45 | tomoj | wonder what new does |
| 06:45 | LauJensen | (defn new [i] (Thread/sleep 30) (Integer/parseInt i)) |
| 06:46 | LauJensen | But yea, its a good question |
| 06:46 | tomoj | NewExpr has a whole lot inside |
| 06:47 | tomoj | HostExpr does too, though |
| 07:20 | jave | I'm trying to do the conjure ajax tutorial, but I'm failing. are the src for the tutorial up somewhere? |
| 07:26 | LauJensen | jave if by conjure you mean Clojure, then I am not aware of any ajax tutorial, got a link? |
| 07:27 | jave | no I mean the conjure web framework that uses clojure |
| 07:27 | jave | http://github.com/macourtney/Conjure |
| 07:28 | jave | it seems neat, but I have aparently missed to perform some step when I tried the ajax tutorial |
| 07:29 | LauJensen | Ah ok, sorry then Im blank, have never tried it |
| 07:29 | jave | np |
| 07:29 | LauJensen | Though I think your the 2nd guy this week to come in here and complain about it |
| 07:30 | jave | oh |
| 07:30 | jave | I'm not complaining mind you |
| 07:30 | LauJensen | alright - Im just saying, I dont think you're the first guy to have trouble with it |
| 07:31 | jave | yep |
| 07:32 | jave | I always wanted to do web coding in lisp, the goal is close at hand, yet far... |
| 07:32 | tomoj | every time I see that "A Rails like framework for Clojure" I get a little crazy |
| 07:33 | LauJensen | jave: A ton of us are doing web coding in Clojure, just not using Conjur |
| 07:33 | somnium | I think there's a tutorial for sproutcore + compojure somewhere |
| 07:33 | jave | cool |
| 07:33 | lenw | http://wiki.sproutcore.com/Todos+06-Building+with+Compojure+and+MongoDB |
| 07:33 | LauJensen | jave: http://bestinclass.dk/index.clj/2009/12/dynamic-interactive-webdevelopment.html |
| 07:33 | bobo_ | i have some ajax stuff i made in compojure/ring/hiccup, if thats to any help. been meening to write something about it but havent yet |
| 07:33 | LauJensen | I did that a while ago, which is a pretty decent intro to webdev |
| 07:34 | LauJensen | jave: http://bestinclass.dk/index.clj/2009/12/beating-the-arc-challenge-in-clojure.html that also shows off some compojure, though its a little outdated. If you want some up to date code, you could check out the source for bestinclass.dk |
| 07:35 | bobo_ | is bestinclass written with compojure? |
| 07:35 | LauJensen | bobo_: Not, Enlive and Moustache |
| 07:35 | LauJensen | s/Not/No |
| 07:35 | LauJensen | I used to use Compojure only for webdev, but when they stripped out all the guts and implemented it as ring middleware, I went with Moustache - Though I think both a fun to work with |
| 07:38 | jave | so, most of the framework uses "ring" then? |
| 07:38 | LauJensen | yes |
| 07:39 | jave | and compojure, does it have some jsquery bindings? |
| 07:39 | LauJensen | jsquery? |
| 07:39 | jave | jquery, sorry |
| 07:40 | bobo_ | jave: no not realy |
| 07:40 | bobo_ | not that ive found atleast. |
| 07:40 | bobo_ | but you can still use it |
| 07:40 | LauJensen | Im not sure. But for one thing, jquery is pretty concise in its own right, and 2nd, it would be easy to wrap some of the syntax |
| 07:40 | bobo_ | i wrote my javascript in javascript |
| 07:40 | tomoj | bobo_: hurrah |
| 07:40 | bobo_ | jquery is imho great as it is. |
| 07:40 | somnium | javascript doesnt get enough love |
| 07:41 | jave | I'm a bit rusty with web dev |
| 07:41 | jave | did used cocoon a lot before |
| 07:41 | jave | I liked the continuations aproach |
| 07:41 | lenw | LauJensen: is there a good intro on using Enlive and Moustache together ? |
| 07:41 | LauJensen | lenw: I wouldn't say 'good', but I talked about it some on my site when I relaunched it |
| 07:42 | lenw | thanks checking it out now |
| 07:42 | somnium | http://box2d-js.sourceforge.net/ |
| 07:42 | somnium | ^^ just saw this today, is there anything like this for swing/awt? |
| 07:42 | LauJensen | lenw: http://bestinclass.dk/blog.html, post #2 and #3 talk about some of the work that went into converting a wordpress blog and relaunching it on Moustache |
| 07:42 | LauJensen | (all source is open) |
| 07:43 | lenw | LauJensen: thanks |
| 07:43 | LauJensen | np |
| 07:43 | somnium | ah, jbox2d |
| 09:11 | mister_m | does clojure support tail call optimization? |
| 09:16 | dnolen_ | mister_m: http://groups.google.com/group/clojure/msg/0de2afb8995c77b5 |
| 09:20 | mister_m | so due to the JVM, the answer is no; use recur |
| 09:24 | LauJensen | yup |
| 09:24 | LauJensen | which works out to be quite painless |
| 09:25 | fogus | Call me crazy, but I like the explicit recur over the implicit recursive self-call |
| 09:25 | mister_m | I could do either personally, but the explicit recur does remove any ambiguity I suppose |
| 09:25 | LauJensen | fogus: thats crazy talk |
| 09:26 | mister_m | off to work I go, thanks for the link to that discussion |
| 09:27 | fogus | if we ever get generalized TCO in the JVM, then maybe we should have another special form (tail-to ...) for the tail call ;-) |
| 09:27 | fogus | mister_m: Yeah, the non-tail error is a win IMO |
| 11:38 | Bootvis | how can I manipulate array maps? |
| 11:40 | lpetit | Bootvis: I don't understand the question |
| 11:42 | Bootvis | I understand, say I get an clojure.lang.PersistentArrayMap from some API and I want to no the first element |
| 11:42 | Bootvis | what should I do |
| 11:42 | Bootvis | this doesn't work |
| 11:42 | Bootvis | ,(first {"foo" "bar"}) |
| 11:42 | clojurebot | ["foo" "bar"] |
| 11:43 | nipra | ,(seq {"foo" "bar"}) |
| 11:43 | clojurebot | (["foo" "bar"]) |
| 11:43 | lpetit | Bootvis: sure, Maps (in general) are not sequential |
| 11:43 | LauJensen | ,(vals {"one" "two"}) |
| 11:43 | clojurebot | ("two") |
| 11:44 | LauJensen | like lpetit said, its a different thing, its key/val based |
| 11:44 | lpetit | Bootvis: PersistentArrayMap, though, will preserve the order of the keys, based on insertion, but it's dangerous to rely on it, I think |
| 11:44 | LauJensen | ,(assoc {:one 1 :two 2} :two 3) |
| 11:44 | clojurebot | {:one 1, :two 3} |
| 11:45 | lpetit | Bootvis: since the assoc, etc. functions on maps will "promote" array maps to hash-maps depending on their size |
| 11:45 | LauJensen | lpetit: Hi Laurent, hows it going? |
| 11:46 | lpetit | (LauJensen: hi ! Good, and you ? |
| 11:46 | Bootvis | ok I'm experimenting with compojure and if I POST a form it returns an array map with the name and content of the fields paired |
| 11:46 | LauJensen | Yea Im doing good thanks. Hows your path-finding in Lyon coming along? |
| 11:46 | Bootvis | so I sure hope that ordering is preserved |
| 11:46 | LauJensen | Bootvis: IIRC thats also a key value pair |
| 11:47 | lpetit | Bootvis: do you really need to know the order the pairs were inserted in ? |
| 11:48 | Bootvis | I guess so, I should know which field has which value |
| 11:48 | lpetit | Bootvis: I think you don't get what maps are. They are associative data structures: they associate a key with a value: { "key1" "val1", "key2" "val2" } . |
| 11:49 | lpetit | Bootvis: array maps are not different in this area, it's just an implementation detail that they are based on arrays internally |
| 11:49 | Bootvis | ok so that is preserved |
| 11:50 | lpetit | Bootvis: so you just call seq on your map and you'll get a seq of pairs of key/value, (the pair will be in a vector) : |
| 11:50 | lpetit | ,(seq {"k1" "v1" "k2" "v2"}) |
| 11:50 | clojurebot | (["k1" "v1"] ["k2" "v2"]) |
| 11:50 | Bootvis | ok I thought that maybe I could access it directly |
| 11:51 | Bootvis | thanks for your time |
| 11:51 | lpetit | Bootvis: why in first place did you know that you got an array map ? |
| 11:52 | Bootvis | I used (class object) |
| 11:53 | lpetit | hmm |
| 11:53 | lpetit | ,(type {"k" "v"}) |
| 11:53 | clojurebot | clojure.lang.PersistentArrayMap |
| 11:53 | AWizzArd | ,shuffle |
| 11:53 | clojurebot | #<core$shuffle clojure.core$shuffle@1ae3e6d> |
| 11:53 | arkh | is it convention to use defn for java methods even if you don't expect the return value to change? E.g. (defn localhost [] (. InetAddress getLocalHost)) could just as easily be (def localhost (. InetAddress getLocalHost)) |
| 11:54 | lpetit | Bootvis: hint = use type instead of class. It will behave the same as class for pure java objects, but it will get you the clojure type which is a more interesting value in some cases |
| 11:55 | lpetit | arkh: not necessarily, what made you think so ? |
| 11:55 | arkh | http://github.com/aberant/clojure-networking/blob/master/server/udp.clj |
| 11:56 | Bootvis | lpetit: thanks |
| 11:56 | arkh | lpetit: aberant's usage wraps methods with defn and values-only with def |
| 11:57 | lpetit | arkh: I do not have strong opinions on this. Don't know of any convention rule 'bout this |
| 11:57 | arkh | lpetit: ok - thank you for looking it over |
| 12:30 | lpetit | arkh: np |
| 13:46 | tnks | new to clojure, is there a decent date/time implementation, or should I use Jota (sp?) |
| 13:47 | tnks | I guess it's JodaTime. |
| 13:48 | technomancy | yes, don't use java.util.Date for any nontrivial calculation. |
| 13:53 | danlarkin | that's right... use chrono!!!11 |
| 13:57 | tnks | danlarkin: thanks, just what we were looking for |
| 13:58 | danlarkin | oh, I was actually being facetious, I don't think chrono has seen much effort |
| 14:34 | dnolen | tnks: you should checkout clj-time, it's built on joda http://github.com/clj-sys/clj-time |
| 14:35 | technomancy | which is really just chrono with a crappier name, innit? |
| 14:37 | LauJensen | technomancy: sure, but just go with my fork instead then "timejure" |
| 15:05 | technomancy | oh snap |
| 15:31 | homie | hulloo |
| 15:31 | homie | can someone help me setup clojure for emacs ? |
| 15:31 | homie | i repeated the steps in the movie to set it up |
| 15:32 | homie | i put the clojure script in my .emacs.d folder which is on a laod-path |
| 15:32 | homie | and the script runs itself from console |
| 15:32 | homie | the part of my .emacs which tells (require 'clojure-autoload) fails though |
| 15:33 | homie | sorry i meant (require 'clojure-auto) |
| 15:34 | LauJensen | homie: which movie? |
| 15:37 | rbe | hi |
| 15:38 | homie | i get this here http://paste.lisp.org/+2FAP |
| 15:38 | rbe | i tried to use an auto-gensym in a macro like this: `(let [x# '(1 2 3)] (first x#)) but i can just access x# without a function call… why? |
| 15:38 | homie | clojure on blip.tv |
| 15:39 | LauJensen | homie: I havent seen that. I have a video on my blog as well you can check if, it you reach a dead end |
| 15:39 | LauJensen | ,`(let [x# [1 2 3]] x#) |
| 15:39 | clojurebot | (clojure.core/let [x__501420__auto__ [1 2 3]] x__501420__auto__) |
| 15:40 | LauJensen | rbe: try (defmacro mac [] `(let [x# [1 2 3]] (first x#))) |
| 15:40 | LauJensen | then run (mac) |
| 15:41 | rbe | laujensen: thanks… i am using a list not a vector… then i get 'unable to resolve symbol x# in this context' |
| 15:42 | rbe | the list is a list of forms and i want to evaluate the first |
| 15:42 | LauJensen | rbe: also with this (defmacro mac [] `(let [x# '(1 2 3)] (first x#))) ? |
| 15:42 | rbe | works also… hm |
| 15:46 | arkh | what is the difference between nil and NIL? |
| 15:47 | cemerick | There is no NIL in clojure. |
| 15:48 | arkh | sorry ... I was reading the code for fill-queue (and seque) and didn't see this: "NIL (Object.) ;nil sentinel since LBQ doesn't support nils" |
| 15:48 | rbe | laujensen: this works but does not evaluate the form: (defmacro mac [& a] `(loop [forms# '~a] (let [f# (first forms#)] f#))) .. (mac (+ 1 1) (+ 2 2)) == (+ 1 1) |
| 15:48 | rbe | adding ~ gives unresolved symbol: |
| 15:48 | rbe | user=> (defmacro mac [& a] `(loop [forms# '~a] (let [f# ~(first forms#)] f#))) |
| 15:48 | rbe | java.lang.Exception: Unable to resolve symbol: forms# in this context (NO_SOURCE_FILE:217) |
| 15:49 | LauJensen | rbe: ~'a is a symbol defined in that namespace, ~a is your argument |
| 15:50 | rbe | but i used '~a as i want the quoted list so not all forms get evaluated |
| 15:50 | rbe | using ~a gives same error |
| 15:51 | raek | a symbol# can only be used within the syntax-quote |
| 15:51 | rbe | seems that ~(first forms#) causes the error |
| 15:51 | raek | it doesn't make sense to mix compile-time and run-time this way |
| 15:51 | rbe | raek: my macro starts with ` |
| 15:52 | LauJensen | rbe: ~(first...) kills the ` |
| 15:52 | raek | yes, but the second occurance is in the unquoted (compile time) section |
| 15:52 | raek | I just joined, so I did not catch what the macro should do |
| 15:52 | LauJensen | rbe: Keep in mind. Macros should be at a minimum in your code. Anything which doesnt require dynamic evaluation should be in an fn |
| 15:53 | LauJensen | raek will take it from here :) |
| 15:53 | raek | LauJensen: if you say so... :) |
| 15:53 | Chousuke | you probably want to loop over the forms in the macro, not in the generated code |
| 15:53 | LauJensen | raek well since you jumped in the middle of it, I'll assume you have more time on your hands than I :) |
| 15:54 | rbe | i just tried to implement a macro evaluating any given forms so i can play around with debugging or statistics… log any form and its execution time |
| 15:54 | Chousuke | ie, something like (defmacro foo [& forms] `(do ~@(for [form forms] `(frobnicate form)))) |
| 15:54 | rbe | looks interesting chosuke |
| 15:55 | Chousuke | and if the autogensyms don't work for you, you can always use manual gensyms :P |
| 15:55 | raek | rbe: evaluate when? compile-time? run-time? |
| 15:56 | rbe | run-time |
| 15:56 | raek | if you just want to wrap some code, try making a function taking a function first |
| 15:56 | kiemdoder | what is the difference between (nth 2 [1 2 3]) and ([1 2 3] 2) ? |
| 15:56 | rbe | raek: i wanted to print the form, its result and the time … so i think it must be macro? |
| 15:56 | raek | ([1 2 3] 2] <=> (get [1 2 3] 2), iirc |
| 15:56 | Chousuke | kiemdoder: no real difference. |
| 15:57 | raek | get and nth behave differently when the index is out of bounds |
| 15:57 | Chousuke | kiemdoder: however, if it's (nth x somevar) vs (somevar x) there is an obvious difference :) |
| 15:57 | raek | if you want to print the form, I would have to |
| 16:00 | raek | (defmacro time-and-print [& forms] `(do (prn '~forms) (time (do ~@forms)))) |
| 16:00 | raek | maybe something like that |
| 16:01 | rbe | ok and now for every form… not the total result |
| 16:01 | rbe | ;) |
| 16:01 | raek | user=> (time-and-print (+ 1 2 3)) |
| 16:01 | raek | ((+ 1 2 3)) |
| 16:01 | raek | "Elapsed time: 0.104762 msecs" |
| 16:01 | raek | 6 |
| 16:01 | raek | ah |
| 16:01 | Chousuke | rbe: just add a for |
| 16:02 | raek | maybe it would be easier to make a macro that does this for one form, and then another that does it for all |
| 16:02 | Chousuke | rbe: you can just do something like (defmacro log-form [& forms] `(do ~@(for [form forms] `(do (log '~form) ~form))))) |
| 16:04 | rbe | yes… looks very good |
| 16:04 | Chousuke | which for (log-form (+ 1 2) (* 2 3)) generates (do (do (log '(+ 1 2)) (+ 1 2)) (do (log '(* 2 3)) (* 2 3))) |
| 16:04 | Chousuke | though that macroexpansion is manual so I make no guarantees :P |
| 16:05 | rbe | had to learn that ` can be used more than once ;) |
| 16:05 | Chousuke | ` actually has nothing to do with macros, really |
| 16:05 | Chousuke | it's just a convenient tool when you're writing them :P |
| 16:06 | Chousuke | but all macros are possible to write without ` |
| 16:06 | rbe | chousuke: why? i just started working with clojure and have to read 3 books i bought recently ;) |
| 16:06 | Chousuke | rbe: ` is a way of constructing code structures easily |
| 16:07 | rbe | ok.. what does it do? |
| 16:07 | Chousuke | I mean, (let [a 5] `(* 1 2 ~a)) constructs the list (clojure.core/* 1 2 5) |
| 16:07 | raek | user> (macroexpand-1 '(log-form (+ 1 2) (* 2 3))) |
| 16:07 | raek | (do (do (user/log (quote (+ 1 2))) (+ 1 2)) (do (user/log (quote (* 2 3))) (* 2 3))) |
| 16:08 | Chousuke | but you can do that just as well by doing (let [a 5] (list '* 1 2 a)) |
| 16:08 | Chousuke | well, except hm |
| 16:08 | rbe | ah… something like a short form? |
| 16:08 | Chousuke | the symbol won't get namespace qualified |
| 16:08 | rbe | when i do `(+ 1 1) i get (clojure.core/+ 1 1) |
| 16:09 | Chousuke | yeah, it does namespace resolution |
| 16:09 | raek | the symbols gets namespace qualified |
| 16:09 | raek | this is to avoid symbol capture |
| 16:09 | Chousuke | rbe: you can think of it as a convenient template syntax |
| 16:09 | Chousuke | rbe: but remember that clojure code is made of data structures, not text, so it's a template for a data structure |
| 16:10 | Chousuke | and where you need such a data structure, you can use ` |
| 16:10 | rbe | 8-) |
| 16:10 | rbe | thanks |
| 16:10 | Chousuke | it works with all clojure data structures too, not just lists |
| 16:11 | Chousuke | ,(let [a 5] `[a b ~a]) |
| 16:11 | clojurebot | [sandbox/a sandbox/b 5] |
| 16:12 | raek | ,`(let [a 1] a) |
| 16:12 | clojurebot | (clojure.core/let [sandbox/a 1] sandbox/a) |
| 16:12 | raek | ah |
| 16:12 | Chousuke | that would actually not work if you emitted that from a macro :) |
| 16:12 | raek | ...and then the compiler refuses to do that let |
| 16:12 | raek | yes |
| 16:13 | Chousuke | yeah. It's a nice solution for the name capture problem. |
| 16:13 | raek | I was thinking if that logic was built in into syntax-quote |
| 16:13 | raek | but i see now that it does not have too |
| 16:13 | raek | very. |
| 16:13 | raek | has this been implemented in another lisp? |
| 16:14 | Chousuke | I don't think so |
| 16:15 | raek | so rich solved this ancient problem as well by himself? |
| 16:15 | raek | man, he |
| 16:16 | Chousuke | I don't know. Maybe he was inspired by something |
| 16:16 | raek | 's smart |
| 16:16 | raek | clojure sure has *a lot* of goodies in it |
| 16:16 | Chousuke | I don't know of other lisps implementing Clojure's solution, but that doesn't mean they don't exist somewhere :D |
| 16:17 | fogus_ | Let Over Lambda has a macro defmacro! (I think that was the name, I do not have my copy here) that works in a similar way |
| 16:17 | Chousuke | Yeah, that's what I like most about it. |
| 16:17 | Chousuke | lots of small things that by themselves are nothing special |
| 16:17 | Chousuke | but then it just kind of works together |
| 16:18 | Chousuke | There are warts too but every language has those :P |
| 16:19 | callen-nyc | Chousuke: the first/last/nth/rest stuff can be a wee inconsistent in nomenclature. |
| 16:19 | callen-nyc | that's my only real complaint of lae. |
| 16:19 | callen-nyc | late |
| 16:20 | rbe | so long … thanks a lot guys… i've got to sleep now |
| 16:20 | rbe | see you |
| 16:26 | kiemdoder | callen-nyc, I agree there often seem to be more than one way to do the same thing which can make it a bit challenging to learn |
| 16:27 | kiemdoder | it being clojure |
| 16:39 | triyo | Does anyone else think this is cool http://hackage.haskell.org/package/DSTM-0.1.1 a framework for using STM within distributed systems? |
| 16:40 | callen-nyc | kiemdoder: yedah. |
| 16:40 | callen-nyc | er, yeah. |
| 16:40 | callen-nyc | kiemdoder: you get past it, but it's kind of *_* compared to [listy, list][slicey] |
| 16:40 | callen-nyc | or object[slice] |
| 16:48 | eckroth | how do I import/use/whatever a record (from defrecord) into another namespace? |
| 16:55 | eckroth | answer to my question: http://tech.puredanger.com/2010/06/30/using-records-from-a-different-namespace-in-clojure/ |
| 17:00 | hoeck | triyo: yes! |
| 17:02 | triyo | hoeck: came across it earler today and thought that it might be something nice to see in Clojure in the future for satisfying distributed models. |
| 17:06 | cemerick | I remember suggesting a while back that require be invoked for the namespaces corresponding to each imported class. That was back when gen-class was the only game in town, so now I'd suggest adding the namespaces corresponding to the package of imported classes. Then (import 'some.package.YourRecord) would automatically attempt to require some.package. |
| 17:25 | eckroth | any opinions? is enclojure better than emacs/slime for larger projects? is enclojure stable, fast? |
| 17:29 | eckroth | enclojure does not have a paredit equivalent, I'm assuming |
| 17:32 | dnolen | eckroth: enclojure certainly seems featureful and stable. tho because of the Java GUI I don't find it particularly fast on my machine. |
| 17:33 | dnolen | eckroth: seems more compelling when you want to integrate with lots of Java libraries. |
| 17:33 | eckroth | dnolen: thanks. that's basically what I feared. I've had painful experiences with Eclipse crashing, so I generalize that to "all big IDEs crash too much" |
| 17:33 | eckroth | dnolen: ah, that could be useful; at the moment, I'm mostly thinking "big clojure project", as in, lots of namespaces and files |
| 17:34 | dnolen | eckroth: I've never had Enclojure crash on me but again I don't use it much. Overall Netbeans seems nicer to me to me than Eclipse. |
| 17:35 | dnolen | eckroth: one thing that I like about Enclojure is excellent symbol navigation |
| 17:35 | eckroth | dnolen: unfortunately, I basically use one IDE for each separate development language; I use Qt Creator for C++ projects, Eclipse for Android projects, Vim for PHP projects (on the server), and Emacs for Clojure projects |
| 17:35 | eckroth | dnolen: I noticed that in the screenshots |
| 17:36 | dnolen | eckroth: that doesn't seem that weird to me :) go with the best tools for the platform. |
| 17:37 | eckroth | dnolen: yeah but they each have their own style (key combinations, for example); keeps me multifunctional (I get to avoid the Vim vs. Emacs debate, for example) but seems a bit of a shame that I can't customize just one environment and be happy |
| 17:37 | dnolen | eckroth: three things that would make Enclojure more compelling to me: 1) eval last sexpr, 2) macroexpand last sexpr, 3) paredit |
| 17:38 | eckroth | dnolen: besides key combinations, each have their own git integration :) magit seems the best so far |
| 17:38 | eckroth | dnolen: yeah I use (1) and (3) all the time; too bad for enclojure |
| 17:39 | dnolen | eckroth: yeah magit is great. I keep meaning to learn some elisp to try my hand at improving Emacs/Clojure. too little time in the day. |
| 17:51 | flintf | I haven't been able to get enclojure working |
| 17:52 | flintf | Well I did awhile ago, but when I tried to use it recently it wouldn't work... |
| 17:53 | eckroth | flintf: that's the kind of annoyance that I want to avoid |
| 18:04 | defn | im so firmly embedded in emacs that another IDE wouldnt probably entice me |
| 18:04 | technomancy | not even Genera? |
| 18:05 | Raynes | defn: Didn't we argue over this a while back where you said that I would be silly to not jump at a nice Clojure IDE just because I liked emacs? |
| 18:07 | defn | yes we did |
| 18:07 | defn | i concede |
| 18:07 | defn | i play devil's advocate on that topic though |
| 18:07 | defn | simply because...well...diff'rent strokes for diff'rent folks |
| 18:08 | rhudson | flintf: at some point it seemed enclojure worked with netbeans 6.8 but not 6.9 -- I don't know if that's been addressed yet |
| 18:08 | defn | technomancy: should i know that reference? I'm not familiar |
| 18:09 | qbg | Genera might be awesome if it worked with Clojure |
| 18:09 | defn | link please? |
| 18:09 | technomancy | it was before your (and my) time: http://en.wikipedia.org/wiki/Genera_(operating_system) |
| 18:09 | defn | oh! |
| 18:10 | defn | well color me young |
| 18:39 | defn | http://bigthink.com/davidheinemeierhansson |
| 18:39 | defn | oops |
| 19:19 | slyrus | yay. SMILES parsing support completed. |
| 19:29 | gfrlog | is it possible to eval code within a different namespace? |
| 19:29 | gfrlog | particularly one created at runtime |
| 19:45 | danielfm | gfrlog: if you syntax quoted (with a backquote) the piece of code, I think should be possible because it expands the symbol names |
| 19:46 | danielfm | , `map |
| 19:46 | clojurebot | clojure.core/map |
| 19:46 | gfrlog | huh? |
| 19:47 | danielfm | , `(reduce + (range 10)) |
| 19:47 | clojurebot | (clojure.core/reduce clojure.core/+ (clojure.core/range 10)) |
| 19:47 | gfrlog | so you mean the code would have to be created in the namespace? |
| 19:47 | danielfm | see how it expanede the name of the symbols? |
| 19:48 | danielfm | for example, let's say that you have a namespace with a few functions in it |
| 19:49 | dsop | if I use (multimethod foo class), how cna I check against Seq? |
| 19:49 | danielfm | if you generate the form with this backquote thing, the symbols will also include the namespace that they belong to, e.g. my-ns/my-function |
| 19:50 | danielfm | that way you won't have to (use ..) that namespace in order to (eval ..) that form |
| 19:51 | gfrlog | the code and the namespace are both loaded at runtime though |
| 19:54 | danielfm | gfrlog: I think it doesn't matter since they can be resolved by the compiler |
| 19:55 | danielfm | gfrlog: can you share some code in http://gist.github.com/ or something? |
| 19:57 | gfrlog | yeah, one second |
| 19:59 | dnolen | technomancy: erg it's been so long since I hacked on leiningen, if I want to use leiningen from source can I just symlink the lein script in the repo and that will use the .clj files in the repo? |
| 20:00 | dnolen | I'm seeing an issue with my nativedeps plugin and need to investigate |
| 20:03 | tomoj | I noticed the readme for lein no longer explains how to do that, I think it used to |
| 20:03 | technomancy | dnolen: that should work. you can bootstrap self-install on snapshots now fwiw. |
| 20:03 | gfrlog | danielfm: here you go http://gist.github.com/507413 |
| 20:03 | dnolen | actually, the problem isn't really nativedeps as far as I can tell but that the native path is no longer set in the latest version of leiningen |
| 20:04 | gfrlog | I decided it can work if I convert the code to a string, preface it with a (ns) call, and use (load-string) |
| 20:04 | gfrlog | but I don't know if that's the nicest way or not |
| 20:06 | gfrlog | I think I've always thought of the load functions as being just for loading definitions, not for evaluating code. But I can't think of any reason why it shouldn't be used for evaluation |
| 20:07 | dnolen | technomancy: hmm, getting could not find file classpath errors, how does the bootstrap self-install work is that documented anywhere ? |
| 20:08 | dnolen | sorry classpath errors when symlinking lein script into my path |
| 20:09 | danielfm | gfrlog: okay, I'm looking into it |
| 20:09 | gfrlog | thanks! |
| 20:12 | danielfm | gfrlog: the first thing I think it can be improved here is the way you generate the code |
| 20:12 | danielfm | gfrlog: why not generate a plain list instead of a string? |
| 20:13 | gfrlog | they're both strings actually |
| 20:13 | gfrlog | sent over http |
| 20:13 | clojurebot | make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive |
| 20:13 | gfrlog | so they have to be strings at some point |
| 20:16 | tomoj | where does this "Overriding previous definition of reference to" thing even come from? |
| 20:16 | tomoj | can't find it in clojure or leiningen |
| 20:16 | danielfm | gfrlog: well, without change much what you did in the gist, the eval will work if you replace the (def code ..) with (def code '(my-ns/x 12)) |
| 20:17 | danielfm | gfrlog: or you can just use that namespace before the eval |
| 20:17 | gfrlog | the first idea is what I'm trying to avoid |
| 20:17 | gfrlog | the second idea makes it hard to get the return value and change the namespace back |
| 20:21 | danielfm | gfrlog: well, you have to tell the compiler somehow how to find that function if it's another namespace... so I don't see a way out of this |
| 20:23 | gfrlog | if there were an (eval-in-ns) macro, that'd be fantastic |
| 20:38 | danielfm | gfrlog: something like (eval-in-ns code 'my-ns) ? |
| 20:46 | technomancy | dnolen: the self-install implementation is like seven lines, it's probably clearer than any docs on it could be. |
| 20:46 | dnolen | technomancy: swank-clojure just calls leiningen's eval-in-project correct? |
| 20:46 | technomancy | yeah |
| 20:46 | technomancy | well, lein swank does. |
| 20:48 | dnolen | technomancy: is leiningen-1.3.0 going to coincide with Clojure 1.2? |
| 20:51 | technomancy | dnolen: probably not, but lein 1.3.1 should. |
| 20:54 | dnolen | technomancy: it's still not clear to me what exactly I have to do to run leiningen from source, are you talking about self-install inside lein.sh ? |
| 20:55 | lancepantz | dnolen: it's actually really easy to bootstrap lein with cake |
| 20:56 | dnolen | lancepantz: how is that done? |
| 20:56 | technomancy | dnolen: there's like three ways to build from source now; check "Building" in the readme. |
| 20:56 | lancepantz | just do cake deps from your lein checkout and symlink the bin |
| 20:56 | technomancy | bin/lein self-install is just the easiest. |
| 20:58 | dnolen | technomancy: sorry, I'm being slow here. I haven't really messed with lein since 1.1.0 |
| 20:58 | dnolen | I just needed to run lein deps |
| 20:58 | dnolen | inside the repo |
| 20:58 | dnolen | lancepantz: yeah I had basically done that |
| 20:58 | dnolen | lancepantz: technomancy: thx much |
| 20:59 | technomancy | aight; cool. |
| 21:00 | dnolen | hmmm |
| 21:00 | dnolen | lein-dev clean works, but lein-dev deps -> null pointer exception |
| 21:03 | gfrlog | danielfm: yes, that's the sort of thing I'd like |
| 21:07 | danielfm | gfrlog: take a look at your gist |
| 21:13 | gfrlog | danielfm: will that work without polluting the current namespace? i.e., are the effects of "use" temporary? |
| 21:14 | danielfm | gfrlog: unfortunately no, that (use ..) will do exactly what it does when used elsewhere |
| 21:16 | danielfm | gfrlog: but if you don't do that, you'd need to fully qualify the symbols in your expressions, e.g. (my-ns/my-fn ...), and also require it for eval-in-ns to work |
| 21:20 | bortreb | anyone here a paredit master? |
| 21:21 | bortreb | I'm wondering, let's say you have something like |
| 21:21 | bortreb | println 1 2 3 |
| 21:21 | bortreb | how do you turn it into (println 1 2 3) in paredit-mode? |
| 21:22 | lancepantz | put your point at the start then type: (, C->, C->, C->, C-> |
| 21:22 | danielfm | bortreb: select the whole thing and press M-( |
| 21:22 | tomoj` | huh, C-> is unbound for me |
| 21:23 | tomoj` | I'd use M-(, C-), C-), C-) |
| 21:23 | lancepantz | that should be C--> |
| 21:23 | lancepantz | as in right arrow |
| 21:24 | gfrlog | danielfm: I think load-string will do what I want, as long as I prefix a "(ns)" declaration |
| 21:24 | tomoj` | arrow keys are the devil :P |
| 21:25 | bortreb | no dice for either C-> or C-) for me, maybe you both have special bindings? |
| 21:25 | gfrlog | how can I check if a var has been defined/bound? |
| 21:26 | lancepantz | bortreb: they both work for me, are you sure your in paredit mode? |
| 21:26 | danielfm | here it works if I put the cursor before 'println', then M-(, then C--> 3x |
| 21:26 | danielfm | no special bindings here |
| 21:26 | danielfm | nice tip btw |
| 21:27 | tomoj | no special bindings here either, and both work |
| 21:32 | danielfm | a nice paredit cheat sheet: http://mumble.net/~campbell/emacs/paredit.html |
| 21:32 | bortreb | for some reason they don't work for me at all |
| 21:33 | bortreb | is there a way to see to what C-) is bound for me? |
| 21:33 | lancepantz | ^C, ^H |
| 21:34 | tomoj | C-h k C-) |
| 21:35 | tomoj | bortreb: what's your C-h v paredit-version ? |
| 21:36 | bortreb | 20 |
| 21:36 | tomoj | from ELPA? |
| 21:36 | bortreb | yeah |
| 21:37 | tomoj | get rid of it, grab http://mumble.net/~campbell/emacs/paredit-beta.el |
| 21:37 | bortreb | ah ok |
| 21:37 | nollidj | anyone here try to use with maven and penumbra together? i think i'm missing a little thing in my pom.xml that's preventing the native deps from being incorporated properly |
| 21:37 | lancepantz | fwiw, i'm on 20 as well |
| 21:37 | danielfm | tomoj, bortreb: in any case, I'm using the ELPA one and those key bindings work fine |
| 21:37 | tomoj | cool |
| 21:38 | tomoj | don't you have curly problems with 20? |
| 21:38 | danielfm | tomoj: I don't even know whatta hell is it.. :) |
| 21:38 | tomoj | clojure-mode detects paredit 21 or greater and fixes {} |
| 21:38 | lancepantz | my curlies don't work |
| 21:38 | lancepantz | and quotes are a pita too |
| 21:38 | tomoj | get the beta then |
| 21:39 | lancepantz | yeah, i'm going to try it out |
| 21:39 | lancepantz | i'm actually slowly trying to migrate off of elpa |
| 21:39 | yonatan_ | gfrlog: i think it's (bound? foo) |
| 21:39 | bortreb | I've remapped my keys so that "9" and "(" are switched, and whenever I try to do C-h k C-), it just gives me the help as if I had typed C-h k C-) |
| 21:39 | danielfm | ahh yeah |
| 21:39 | gfrlog | '(bound? x) |
| 21:39 | gfrlog | ,(bound? x) |
| 21:39 | clojurebot | java.lang.Exception: Unable to resolve symbol: x in this context |
| 21:39 | bortreb | it's like it can't see the Ctrl modifier |
| 21:39 | gfrlog | ,bound? |
| 21:39 | clojurebot | #<core$bound_QMARK_ clojure.core$bound_QMARK_@18598b6> |
| 21:39 | gfrlog | I must have an old clojure |
| 21:40 | gfrlog | mine doesn't work |
| 21:40 | gfrlog | I'll use a try-catch |
| 21:40 | bortreb | in the latest clojure bound? doesn't work like that either |
| 21:40 | bortreb | it tries to evaulate the dubious symbol |
| 21:40 | lancepantz | bortreb: does it catch the npe now? |
| 21:40 | gfrlog | apparently it doesn't in clojure-bot either |
| 21:41 | gfrlog | ,(clojure-version) |
| 21:41 | clojurebot | "1.2.0-master-SNAPSHOT" |
| 21:41 | tomoj | here's my bit from init.el for paredit: https://gist.github.com/d426a96b5f5a5fca6cd6 |
| 21:42 | yonatan_ | ,(bound? (var bound?)) |
| 21:42 | clojurebot | true |
| 21:42 | yonatan_ | ,(bound? (var foo)) |
| 21:42 | clojurebot | true |
| 21:42 | mister_m | clojure code looks a lot scarier than perl code I think. |
| 21:43 | danielfm | tomoj: thanks! |
| 21:44 | rhudson | mister_m: It gets a lot less scary once you get used to it. (Perl code stays scary, in my view) |
| 21:50 | pdk | the funky indentation style you see in a lot of lisp code is there to help deemphasize all the parens |
| 21:51 | mister_m | it's not the parens that bother me really |
| 21:52 | mister_m | all the extra symbols are what distract me, but as rhudson said, it just takes getting used to |
| 21:52 | mister_m | I'm still in the 'getting used to' period |
| 21:52 | pdk | by the by for folks using vimclojure here is there a command to reindent a whole block like in emacs |
| 21:56 | mister_m | I should try to start a project so I can do some actual coding with clojure |
| 21:56 | mister_m | instead of fooling with the REPL |
| 21:57 | rhudson | Good idea, except I would recommend "in addition to" in place of "instead of" |
| 21:57 | mister_m | rhudson, yes, that is certainly better |
| 21:58 | rhudson | One of the great things about using Clojure is you get to keep playing with the repl! |
| 22:04 | mister_m | I'm not sure if I like the Programming Clojure book very much though. |
| 22:04 | mister_m | yet |
| 22:04 | rhudson | Why not? |
| 22:04 | lancepantz | mister_m: the joy of clojure is much much better |
| 22:05 | lancepantz | i didn't like programming clojure either |
| 22:06 | mister_m | rhudson, it seems really very rushed |
| 22:06 | rhudson | I thought it was a very good intro book. |
| 22:07 | lancepantz | ,(def *foo* (atom 0))(binding [*foo* (swap! *foo* inc)](println *foo*)) |
| 22:07 | clojurebot | DENIED |
| 22:08 | rhudson | mister_m: what other languages do you know? |
| 22:08 | lancepantz | guess i can't def vars |
| 22:08 | mister_m | rhudson, I've used java before |
| 22:08 | tomoj | lancepantz: sexpbot will let you |
| 22:08 | lancepantz | anyways, in that above, why do i not have to dereference *foo* to print it? |
| 22:08 | lancepantz | sexpbot: (def *foo* (atom 0))(binding [*foo* (swap! *foo* inc)](println *foo*)) |
| 22:08 | sexpbot | This command is old. Use -> now. It's a hook, so it can evaluate anything, even stuff that doesn't start with parentheses. |
| 22:09 | lancepantz | shouldn't i have to (println @*foo*)? |
| 22:10 | tomoj | -> (let [x (atom 0) y (swap! x inc)] (class y)) |
| 22:10 | sexpbot | => java.lang.Integer |
| 22:10 | rhudson | mister_m: I had a lot more languages, including some functional ones, before I got to Clojure, so our experience of the book is undoubtedly different. |
| 22:11 | lancepantz | so atom doesn't turn ints into refs? |
| 22:11 | tomoj | huh? |
| 22:11 | rhudson | ,(println (atom 0)) |
| 22:11 | tomoj | it's just that swap! returns the value, not the atom |
| 22:11 | clojurebot | #<Atom@c73a54: 0> |
| 22:11 | lancepantz | ah |
| 22:11 | rhudson | ,(println @(atom 0))) |
| 22:11 | lancepantz | i see |
| 22:11 | clojurebot | 0 |
| 22:12 | lancepantz | right, i was misunderstanding swap |
| 22:13 | mister_m | rhudson, I'm sure that is true. I'm pretty green. |
| 22:13 | mister_m | so to speak |
| 22:13 | rhudson | mister_m: you have a lot of fun ahead of you |
| 22:27 | bortreb | how do you translate this into clojure? HttpZipLocator.class.getName() |
| 22:28 | rhudson | (.getName HttpZipLocator) |
| 22:28 | mefesto | (.getName (class HttpZipLocator)) |
| 22:29 | bortreb | those are different though |
| 22:29 | bortreb | ,String |
| 22:29 | clojurebot | java.lang.String |
| 22:29 | rhudson | ,(.getName String) |
| 22:29 | clojurebot | "java.lang.String" |
| 22:29 | tomoj | is .class a way to get the Class object of a class? never saw that before |
| 22:29 | bortreb | ,(.getName (class String)) |
| 22:29 | clojurebot | "java.lang.Class" |
| 22:29 | wwmorgan | how can I do (apply concat colls) lazily? |
| 22:30 | bortreb | so which is it>? |
| 22:30 | mefesto | bortreb: rhudson is the right way to go :) |
| 22:30 | bortreb | I'll never get java and it's random bloat.... |
| 22:31 | pdk | testing |
| 22:31 | mister_m | rhudson, one thing specifically I don't like about the Programming Clojure book so far, is the invocation of Java string methods while trying to teach the core language |
| 22:31 | pdk | (doc apply) |
| 22:31 | clojurebot | "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq." |
| 22:31 | pdk | maybe you could wrap your apply form in a lazy-seq call? |
| 22:31 | pdk | (lazy-seq (apply ... |
| 22:32 | rhudson | or use lazy-cat maybe |
| 22:32 | pdk | (doc lazy-cat) |
| 22:32 | clojurebot | "([& colls]); Expands to code which yields a lazy sequence of the concatenation of the supplied colls. Each coll expr is not evaluated until it is needed. (lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))" |
| 22:32 | pdk | (doc cat) |
| 22:32 | clojurebot | Pardon? |
| 22:32 | pdk | (doc concat) |
| 22:32 | clojurebot | "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls." |
| 22:32 | rhudson | ... lazy-cat is a macro though, so apply won't work with it. |
| 22:33 | pdk | god damn kitty |
| 22:33 | wwmorgan | yes. And apply isn't lazy, so (lazy-seq (apply concat colls)) won't work |
| 22:33 | pdk | can't apply its talents to any work |
| 22:35 | tomoj | isn't (apply concat colls) already lazy? |
| 22:35 | tomoj | -> (take 3 (apply concat (repeatedly #(iterate inc 0)))) |
| 22:35 | sexpbot | => (0 1 2) |
| 22:35 | wwmorgan | tomoj: very interesting. I didn't know that worked :-) |
| 22:37 | tomoj | maybe that's not the laziness you're looking for? |
| 22:38 | wwmorgan | no, it's exactly right. I don't know why I thought apply couldn't be lazy |
| 22:39 | rhudson | mister_m: I don't remember that. Like where? (i have the book at hand) |
| 22:42 | tomoj` | was the lazy apply concat question answered while I was away? |
| 22:42 | tomoj | -> (first (apply concat (repeatedly #(do (println "foo") (iterate inc 0))))) |
| 22:43 | sexpbot | => foo foo foo foo 0 |
| 22:43 | tomoj | why 4 of them? |
| 22:43 | pdk | it's laughing at you |
| 22:44 | pdk | that's why it's going foo foo foo |
| 22:44 | tomoj | oh, it's because the last def for apply is ([f a b c d & args]) |
| 22:44 | pdk | though im curious why this bot is different from clojurebot |
| 22:45 | tomoj | but: |
| 22:45 | tomoj | -> (first (apply concat (repeatedly (fn [] (do (println "foo") (iterate #(do (println %) (inc %)) 0)))))) |
| 22:45 | sexpbot | => foo foo foo foo 0 |
| 22:45 | mister_m | rhudson, page 58 sticks out |
| 22:45 | tomoj | so isn't it already lazy enough? |
| 23:13 | mister_m | should I make some orange chicken at 10:12 at night? |
| 23:13 | mister_m | I'm tempted |
| 23:14 | mister_m | reaaaaally tempted |
| 23:58 | pdk | oh snap |
| 23:58 | pdk | how come you guys had to be meanies and not tell me about defn- earlier |
| 23:58 | pdk | i'm telling mommy |
| 23:59 | Raynes | pdk: You should just *know*. ;P |