#clojure log - Aug 03 2010

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:31 notsonerdysunny: I was looking around for sexp like serialization this morning and found

0:31 http://en.wikipedia.org/wiki/Canonical_S-expressions

0:32 http://people.csail.mit.edu/rivest/sexp.html

0:32 it would be nice to have clojure-based interface for it ..

0:48 whats a good way to do clojure and java native stuff ?

0:49 qbg: JNI?

0: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

2: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?

2:51 an enclosing let to squirrel away the old binding?

2:51 works, but I don't suppose there's a more flet-y form I'm missing?

2:55 Chousuke: slyrus: can't you do just (let [foo (fn ...)] ...)

2:56 tomoj: slyrus: why does it matter? just curious, not saying it doesn't

2:56 slyrus: I sure can Chousuke, thanks!

2:57 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.

2:57 tomoj: do you often want to do that?

2:58 oh, I think I see

2:58 slyrus: (defn foo [x] (+ 17 x)) (let [foo (fn [x] (+ 33 (foo x)))] (foo 3))

2:58 tomoj: right

2:58 slyrus: sure, I'm adding 33 and 17 to numbers all the time!

2:58 :)

2:58 tomoj: just never wanted to shadow like that before

2:58 but I think I can imagine situations where it would be useful

2:59 Chousuke: slyrus: I'd rather do (let [orig-foo foo] ...). Shadowing like that is pretty confusing

2:59 brehaut: would letfn be closer ?

3:00 slyrus: brehaut: letfn doesn't work as it would just recursively call foo

3:00 brehaut: oh right

3: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.

3:29 raek: good morning

3:30 brehaut: hi raek

3:43 paredit bindings in counterclockwise have made my day

3:47 esj: morning all

4:04 LauJensen: Good morning all

4:05 (incl. esj)

4:05 brehaut: evening

4:05 * esj feels special :)

4:11 sid3k: morning guys

4:12 LauJensen: Morning sid3k :)

4:14 esj: yo

4:14 xkb: yoyo

5:28 cais2002: how do I convert a str to a number ?

5:31 AWizzArd: cais2002: use the wrapper classes Integer, Long, Byte, etc.

5:31 ,(Integer/parseInt "55")

5:31 clojurebot: 55

5:32 cais2002: -> (Integer. "55")

5:32 sexpbot: => 55

5:32 cais2002: is there a simpler way?

5:32 ,(str 55)

5:32 clojurebot: "55"

5:32 tomoj: there's (read-string "55"), but...

5:33 AWizzArd: this is less efficient, but if you are not in a tight loop it might be okay

5:34 tomoj: how exactly is (Integer. "55") complicated?

5:34 AWizzArd: cais2002: a pretty safe way for conversion is instantiating a BigDecimal, as this can eat all your numbers

5:35 cais2002: tomoj: i thought there is some "native" function to do it

5:35 tomoj: java hater? :)

5:35 zmila: ,(type (load-string "1234"))

5:35 clojurebot: DENIED

5:36 zmila: ,(load-string "1234")

5:36 clojurebot: DENIED

5:37 tomoj: -> (class (read-string "1234"))

5:37 sexpbot: => java.lang.Integer

5:37 AWizzArd: load-string is about the most inefficient way to do this

5:38 tomoj: something like (read-string "{}") will work fine until you try to use it as a number, (Integer. "{}") will properly blow up

5: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

5:38 it's like (eval ) ?

5: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

5:39 tomoj: huh

5:39 why does it take so long for a number to eval to itself?

5:40 oh, load-string isn't (comp eval read-string)

5:41 AWizzArd: right

5:42 tomoj: .. (load-string "1.234 (launch-the-nukes)")

5:42 AWizzArd: Really, if it is an int, just call Integer. on it.

5:44 cais2002: yeah, I will just use Integer/parseInt

5:44 zmila: and wrap into (catch NumberFormatExc)

5:45 cais2002: ah yes

6:26 LauJensen: AWizzArd: Did you bench Integer. vs Integer/parseInt ?

6:29 ,(time (dotimes [_ 1e6] (Integer. "55")))

6:29 clojurebot: "Elapsed time: 157.381 msecs"

6:29 LauJensen: ,(time (dotimes [_ 1e6] (Integer/parseInt "55")))

6:29 clojurebot: "Elapsed time: 106.514 msecs"

6:33 tomoj: that's odd

6:34 bobo_: LauJensen: hows the plans for next round of conj-labs going? saw something about trouble finding a venue?

6: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

6:35 bobo_: great!

6:37 LauJensen: Yea we're really putting in some work to ensure that it indeed becomes 'great' :)

6:37 bobo_: :-)

6:37 esj: LauJensen: where is the content going to be aimed ?

6:38 LauJensen: esj: We'll aim it at the attendants :9

6:38 What do you mean?

6:38 esj: hahahahah

6:38 i mean are you giving 1). An introduction to Clojure, 2). An exploration of certain ideas in Clojure 3). Advanced concurrency coding etc etc ?

6:39 AWizzArd: LauJensen: yes, I tried Integer. vs. Integer/parseInt, and they are virtually equally efficient

6: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) :)

6:40 tomoj: parseInt does seem to be reliably a little tiny bit faster to me, wonder why

6:40 LauJensen: AWizzArd: I always found parseInt to be about 30% faster

6:41 tomoj: I'm seeing more like 3%

6:42 AWizzArd: LauJensen: please try (time (dotimes [i 10000000] (Integer. (str i ))))

6:42 tomoj: it must be that new is slower than . ?

6:43 AWizzArd: and (time (dotimes [i 10000000] (Integer/parseInt (str i))))

6:43 ,(time (dotimes [i 100000] (Integer. (str i ))))

6:43 clojurebot: "Elapsed time: 58.767 msecs"

6:43 AWizzArd: ,(time (dotimes [i 100000] (Integer/parseInt (str i ))))

6:43 clojurebot: "Elapsed time: 58.959 msecs"

6:44 Bahman: Hi all!

6:44 LauJensen: Bahman: yo

6:44 Bahman: Hi there LauJensen!

6:44 tomoj: still ~3% faster it seems

6:45 LauJensen: Yea also a little faster locally

6:45 tomoj: wonder what new does

6:45 LauJensen: (defn new [i] (Thread/sleep 30) (Integer/parseInt i))

6:46 But yea, its a good question

6:46 tomoj: NewExpr has a whole lot inside

6:47 HostExpr does too, though

7:20 jave: I'm trying to do the conjure ajax tutorial, but I'm failing. are the src for the tutorial up somewhere?

7:26 LauJensen: jave if by conjure you mean Clojure, then I am not aware of any ajax tutorial, got a link?

7:27 jave: no I mean the conjure web framework that uses clojure

7:27 http://github.com/macourtney/Conjure

7:28 it seems neat, but I have aparently missed to perform some step when I tried the ajax tutorial

7:29 LauJensen: Ah ok, sorry then Im blank, have never tried it

7:29 jave: np

7:29 LauJensen: Though I think your the 2nd guy this week to come in here and complain about it

7:30 jave: oh

7:30 I'm not complaining mind you

7:30 LauJensen: alright - Im just saying, I dont think you're the first guy to have trouble with it

7:31 jave: yep

7:32 I always wanted to do web coding in lisp, the goal is close at hand, yet far...

7:32 tomoj: every time I see that "A Rails like framework for Clojure" I get a little crazy

7:33 LauJensen: jave: A ton of us are doing web coding in Clojure, just not using Conjur

7:33 somnium: I think there's a tutorial for sproutcore + compojure somewhere

7:33 jave: cool

7:33 lenw: http://wiki.sproutcore.com/Todos+06-Building+with+Compojure+and+MongoDB

7:33 LauJensen: jave: http://bestinclass.dk/index.clj/2009/12/dynamic-interactive-webdevelopment.html

7: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

7:33 LauJensen: I did that a while ago, which is a pretty decent intro to webdev

7:34 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

7:35 bobo_: is bestinclass written with compojure?

7:35 LauJensen: bobo_: Not, Enlive and Moustache

7:35 s/Not/No

7:35 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

7:38 jave: so, most of the framework uses "ring" then?

7:38 LauJensen: yes

7:39 jave: and compojure, does it have some jsquery bindings?

7:39 LauJensen: jsquery?

7:39 jave: jquery, sorry

7:40 bobo_: jave: no not realy

7:40 not that ive found atleast.

7:40 but you can still use it

7: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

7:40 bobo_: i wrote my javascript in javascript

7:40 tomoj: bobo_: hurrah

7:40 bobo_: jquery is imho great as it is.

7:40 somnium: javascript doesnt get enough love

7:41 jave: I'm a bit rusty with web dev

7:41 did used cocoon a lot before

7:41 I liked the continuations aproach

7:41 lenw: LauJensen: is there a good intro on using Enlive and Moustache together ?

7:41 LauJensen: lenw: I wouldn't say 'good', but I talked about it some on my site when I relaunched it

7:42 lenw: thanks checking it out now

7:42 somnium: http://box2d-js.sourceforge.net/

7:42 ^^ just saw this today, is there anything like this for swing/awt?

7: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

7:42 (all source is open)

7:43 lenw: LauJensen: thanks

7:43 LauJensen: np

7:43 somnium: ah, jbox2d

9:11 mister_m: does clojure support tail call optimization?

9:16 dnolen_: mister_m: http://groups.google.com/group/clojure/msg/0de2afb8995c77b5

9:20 mister_m: so due to the JVM, the answer is no; use recur

9:24 LauJensen: yup

9:24 which works out to be quite painless

9:25 fogus: Call me crazy, but I like the explicit recur over the implicit recursive self-call

9:25 mister_m: I could do either personally, but the explicit recur does remove any ambiguity I suppose

9:25 LauJensen: fogus: thats crazy talk

9:26 mister_m: off to work I go, thanks for the link to that discussion

9: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 ;-)

9:27 mister_m: Yeah, the non-tail error is a win IMO

10:09 * defn wipes sleep out of his eyes

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 what should I do

11:42 this doesn't work

11:42 ,(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 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 ,(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 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 ,(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 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 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 can someone help me setup clojure for emacs ?

15:31 i repeated the steps in the movie to set it up

15:32 i put the clojure script in my .emacs.d folder which is on a laod-path

15:32 and the script runs itself from console

15:32 the part of my .emacs which tells (require 'clojure-autoload) fails though

15:33 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 ,`(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 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 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 adding ~ gives unresolved symbol:

15:48 user=> (defmacro mac [& a] `(loop [forms# '~a] (let [f# ~(first forms#)] f#)))

15:48 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 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 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 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 (defmacro time-and-print [& forms] `(do (prn '~forms) (time (do ~@forms))))

16:00 maybe something like that

16:01 rbe: ok and now for every form… not the total result

16:01 ;)

16:01 raek: user=> (time-and-print (+ 1 2 3))

16:01 ((+ 1 2 3))

16:01 "Elapsed time: 0.104762 msecs"

16:01 6

16:01 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 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 it's just a convenient tool when you're writing them :P

16:06 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 (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 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 this is to avoid symbol capture

16:09 Chousuke: rbe: you can think of it as a convenient template syntax

16:09 rbe: but remember that clojure code is made of data structures, not text, so it's a template for a data structure

16:10 and where you need such a data structure, you can use `

16:10 rbe: 8-)

16:10 thanks

16:10 Chousuke: it works with all clojure data structures too, not just lists

16:11 ,(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 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 but i see now that it does not have too

16:13 very.

16:13 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 man, he

16:16 Chousuke: I don't know. Maybe he was inspired by something

16:16 raek: 's smart

16:16 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 lots of small things that by themselves are nothing special

16:17 but then it just kind of works together

16:18 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 that's my only real complaint of lae.

16:19 late

16:20 rbe: so long … thanks a lot guys… i've got to sleep now

16:20 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 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 er, yeah.

16:40 kiemdoder: you get past it, but it's kind of *_* compared to [listy, list][slicey]

16:40 or object[slice]

16:48 eckroth: how do I import/use/whatever a record (from defrecord) into another namespace?

16:55 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 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 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 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 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 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 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 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 i concede

18:07 i play devil's advocate on that topic though

18:07 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 well color me young

18:39 http://bigthink.com/davidheinemeierhansson

18:39 oops

19:19 slyrus: yay. SMILES parsing support completed.

19:29 gfrlog: is it possible to eval code within a different namespace?

19:29 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 , `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 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 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 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 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 but I don't know if that's the nicest way or not

20:06 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 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 gfrlog: why not generate a plain list instead of a string?

20:13 gfrlog: they're both strings actually

20:13 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 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 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 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 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 I just needed to run lein deps

20:58 inside the repo

20:58 lancepantz: yeah I had basically done that

20:58 lancepantz: technomancy: thx much

20:59 technomancy: aight; cool.

21:00 dnolen: hmmm

21:00 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 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 I'm wondering, let's say you have something like

21:21 println 1 2 3

21:21 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 I'd use M-(, C-), C-), C-)

21:23 lancepantz: that should be C-->

21:23 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 no special bindings here

21:26 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 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 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 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 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 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 ,(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 mine doesn't work

21:40 I'll use a try-catch

21:40 bortreb: in the latest clojure bound? doesn't work like that either

21:40 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 ,(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 all the extra symbols are what distract me, but as rhudson said, it just takes getting used to

21:52 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 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 yet

22:04 rhudson: Why not?

22:04 lancepantz: mister_m: the joy of clojure is much much better

22:05 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 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 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 ,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 (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 -> (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 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 -> (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 I'm tempted

23:14 reaaaaally tempted

23:58 pdk: oh snap

23:58 how come you guys had to be meanies and not tell me about defn- earlier

23:58 i'm telling mommy

23:59 Raynes: pdk: You should just *know*. ;P

Logging service provided by n01se.net