#clojure log - May 03 2010

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

0:02 LeNsTR: yep

0:03 eliantor: is it a right fold?

0:05 defn: eliantor: http://gist.github.com/96861

0:05 that is

0:09 eliantor: but it consumes the stack

0:09 does it work the same using trampoline?

0:42 joshua-choi: Question: does clojure.contrib.def/defalias work on macros? It doesn't seem to.

0:44 _ato: ~def clojure.contrib.def/defalias

0:46 hmm.. preserves metadata which should be the main thing

0:46 joshua-choi: Yeah, I thought so too, but it doesn't seem to act correctly.

0:46 Can I try it here?

0:47 _ato: nah, def won't work with clojurebot

0:48 seems to work for me http://gist.github.com/387763

0:48 I haven't tried with git master though, there's been some changes to macros

0:50 joshua-choi: Yes, I'll try git pull again for both clojure and contrib and see if that fixes it

0:52 _ato: Pulling and rebuilding both clojure and contrib did not fix it for me

0:53 Try using this macro instead: (defmacro a [x] `'~x)

0:53 And (defalias b a) (b y).

0:59 _ato: ah.. yep doens't seem to work with 1.2

0:59 remleduff: Do your compojure apps end up doing a ton of (str "/" var "/" var2) ?

1:06 joshua-choi: remleduff: Seems like there should be a helper method. At least (clojure.contrib.string/join "/"

1:06 Ugh, I pressed enter early

1:06 _ato: Can you see the reason why? Should I file a ticket?

1:36 Licenser_: morning

2:09 defn: when i do something i a try/catch, if i am able to catch the error and fix what the problem is, will that then get evaluated?

2:10 i have something like:

2:10 ,(read-string "[Ljava.lang.String;")

2:10 clojurebot: java.lang.RuntimeException: java.lang.Exception: EOF while reading

2:10 defn: however, more than just this case blows up the reader

2:10 so id like to just:

2:11 ,(read-string "\" [Ljava.lang.String;\"")

2:11 clojurebot: " [Ljava.lang.String;"

2:11 defn: whenever it catches

2:16 Licenser_: defn: why would you want that?

2:17 defn: while the reader doesnt like them, they are still helpful for some examples

2:17 Licenser_: (let [s "[Ljava.lang.String;"] (= (read-string (str \" s \")) s))

2:18 ,(let [s "[Ljava.lang.String;"] (= (read-string (str \" s \")) s))

2:18 clojurebot: true

2:18 defn: drop the ]

2:18 Licenser_: what]?

2:18 there is no ] in the string

2:18 defn: ohh sorry, had to expand my window

2:19 Licenser_: [Ljava.langString is just a notation for a string array I think

2:19 defn: Licenser_: i know I can handle that specific case, but there are other cases ive run into like #<foo$bar>

2:19 i'd like to just quit thinking about that part of the equation and escape it as a string when it comes up

2:20 "oh hey this didnt work!" -> make it a string

2:20 Licenser_: so you want to escape stuff within an expression if it fails?=

2:20 defn: -> now read it

2:20 i just want to escape the whole expression as a string when it fails

2:20 and go about my business

2:20 Licenser_: but you already have the result of it

2:21 defn: right, but it's not pretty printed. I need to read-string on the code/results to pretty print them, some of the "good" results still blow up due to things like #<, [Ljava;, and other cases I'm probably not aware of

2:23 Licenser_: (read-string (escape-as-stringe code-string)) = code-string

2:23 defn: there is no difference

2:23 defn: yes, but that will escape everything i do as a string, and therefore no syntax highlighting will happen

2:23 Licenser_: it is just eating computation power

2:24 but "\" ...\"" is the same o.O it escapes everything as a sting

2:24 or do you want to escape like parts of the code string as a string

2:24 so (type [Lblabla;) to (type "Lblabla;")?

2:24 vIkSiT: hmm, whats the best/most idiomatic method of implementing a while loop?

2:24 (loop .. ) ?

2:24 Licenser_: vIkSiT: while?

2:25 (doc while)

2:25 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

2:25 vIkSiT: er weird. should look that up :)

2:25 i couldn't find any docs for "clojur while loop" heh

2:25 Licenser_: $walton while

2:25 sexpbot: Command not found. No entiendo lo que estás diciendo.

2:25 Licenser_: $example while

2:25 sexpbot: Command not found. No entiendo lo que estás diciendo.

2:26 Licenser_: $oh go and die you stupid bopt

2:26 sexpbot: Command not found. No entiendo lo que estás diciendo.

2:26 vIkSiT: :)

2:30 Chousuke: vIkSiT: note that you need a side-effect in the condition for that to make any sense.

2:31 I suppose (while @running ...) is somewhat common

2:34 Licenser_: Chousuke: don't take me the joy of making vIkSiT do a infinit lopop :P

2:35 Chousuke: :P

2:41 defn: Licenser_: erm im not sure if i see what you're saying with respect to escaping with str

2:41 Licenser_: if the string cannot be read by the reader and throws an exception I want to escape it as a string

2:42 "\"foo\"" works where "foo" doesn't when it comes to read-string

2:42 ,(read-string "#<foo$bar")

2:42 clojurebot: java.lang.RuntimeException: java.lang.Exception: Unreadable form

2:42 defn: ,(read-string "\"#<foo$bar\"")

2:42 clojurebot: "#<foo$bar"

2:43 Licenser_: defn: do you notice that the result of (read-string "\"#<foo$bar\"") is exactly the unescaped string?

2:43 if it fails just don't use read-string at all

2:43 defn: it isn't always

2:44 Licenser_: yes it is unless you have a " in the middle of your string, then it breaks

2:44 defn: right, but that's yet another corner case -- because many of them do

2:44 Licenser_: assuming you escape your string correctly then the result is, by definition the same

2:45 defn: ,(read-string "[{111 #<Ref@1bc7fae5: :somestruct>} {\"bob\" #<Ref@1bc7fae5: :somestruct>}]")

2:45 clojurebot: java.lang.RuntimeException: java.lang.Exception: Unreadable form

2:45 Licenser_: you could use (identity ) to escape and read-string it

2:45 defn: ,(read-string "\"[{111 #<Ref@1bc7fae5: :somestruct>} {\"bob\" #<Ref@1bc7fae5: :somestruct>}]\"")

2:45 clojurebot: "[{111 #<Ref@1bc7fae5: :somestruct>} {"

2:46 defn: the reader is a harsh mistress

2:46 Licenser_: so having read-string and escape bill not only consume computation power for nothing but also add bugs ':p

2:46 defn: read-string is necessary though, im confused as to what you're saying

2:47 Licenser_: defn: I'm saying it is not

2:47 you can use identity instead of (read-string (str \" ... \"))

2:47 that saves yourself trouble and time :P

2:48 defn: that doesn't make sense though?

2:48 ,(pprint (identity "foo"))

2:48 clojurebot: "foo"

2:48 defn: ,(pprint (read-string "foo"))

2:48 clojurebot: foo

2:48 Licenser_: yes thaqt is for a good case

2:48 but in a bad case you can use identity

2:49 defn: ah-ha, i see what you mean now

2:49 tomoj: the problem is how to get to the bad cases

2:49 read-string doesn't give you any hooks

2:50 you'd have to rebuild some of read-string

2:50 Licenser_: (let [s "bla bla"] (try (read-string s) (catch Exception _ (identity s)))

2:50 ,(let [s "bla bla"] (try (read-string s) (catch Exception _ (identity s)))

2:50 clojurebot: Licenser_: It's greek to me.

2:50 Licenser_: ,(let [s "bla bla"] (try (read-string s) (catch Exception _ (identity s)))

2:50 clojurebot: Licenser_: Titim gan éirí ort.

2:50 Licenser_: something like that

2:51 defn: Licenser_: so will that string in the catch be passed up to pprint that lies outside of your let?

2:51 tomoj: I'd assume you want only the unreadable forms as strings, not the whole top-level form?

2:51 defn: tomoj: the top-level is fine, actually

2:51 tomoj: strange, why?

2:51 Licenser_: (let [s "[bla bla"] (try (read-string s) (catch Exception _ (identity s))))

2:51 defn: tomoj: most of them are pretty short

2:51 Licenser_: ,(let [s "[bla bla"] (try (read-string s) (catch Exception _ (identity s))))

2:51 clojurebot: Licenser_: Huh?

2:52 Licenser_: welll that code works just not in clojurebot

2:52 $(let [s "[bla bla"] (try (read-string s) (catch Exception _ (identity s))))

2:52 sexpbot: result: [bla bla

2:52 tomoj: so.. any input which contains an unreadable form somewhere will just be passed straight through?

2:52 defn: sexpbot: yeah, they've already been evaluated in a sandbox, this is just output i want to pretty print

2:52 it's just what they've been evaluated to isnt always something the reader likes

2:53 #<foo$bar> for instance

2:53 tomoj: so any of them which contain unreadable forms will be ugly printed?

2:53 Licenser_: why would you want to read the result of a evaluation?

2:53 defn: yeah, but out of 211 examples there are maybe 7 or 8 of them

2:54 Licenser_: to pretty print it

2:54 Licenser_: defn: that isn't good

2:54 that will or might chane the result and that usually isn't what you want

2:54 tomoj: when would it change the result?

2:55 defn: it should just read it as code and pprint it, it's not changing anything

2:56 Licenser_: ,"#(+ 1 %)"

2:56 clojurebot: "#(+ 1 %)"

2:57 tomoj: you're doing this to the return values of code run by bots?

2:57 Licenser_: ,(read-string "#(+ 1 %)"

2:57 clojurebot: EOF while reading

2:57 Licenser_: ,(read-string "#(+ 1 %)")

2:57 clojurebot: (fn* [p1__13903] (+ 1 p1__13903))

2:57 Licenser_: in that case for instance

2:58 even worst, reader eval :P

2:59 which would rip a huge security hole in your code defn

3:01 tomoj: ,(println "#=(println \"foo\")")

3:01 clojurebot: #=(println "foo")

3:01 Licenser_: now if you read that weeh!

3:02 tomoj: it'S not about printing it

3:02 'ss~ about read-string the result of an expression

3:02 tomoj: I know

3:02 but I think the source is bot output, right?

3:02 Licenser_: ,"#=(println \"foo\")"

3:02 clojurebot: "#=(println \"foo\")"

3:02 Licenser_: now read-eval that :P

3:02 tomoj: so we can just print out strings that contain whatever code we want to run on defn's machine

3:03 Licenser_: tomoj: yap

3:03 defn: ? read-string doesn't eval the code though, does it?

3:04 tomoj: indeed it does

3:04 defn: damn...

3:04 tomoj: if it's reader eval

3:04 defn: that sucks...

3:04 tomoj: (read-string "(println \"foo\")") is fine

3:04 but (read-string "#=(println \"foo\")") will print

3:04 defn: #=... isn.t though

3:04 well I can just escape #= strings

3:04 that's not hard

3:05 Licenser_: defn: it still changes the results :(

3:06 defn: Licenser_: im confused, how?

3:06 http://getclojure.org:8080/examples/dorun

3:06 sexpbot: "dorun"

3:07 defn: notice example three is now formatted nicely using pprint and read-string

3:07 yes you do get some weirdness with anonymous functions, but they are still largely readable

3:07 Licenser_: defn: it's still bad practice :P

3:07 defn: if i just get rid of the #= at the beginning of a string, wont that solve the problem?

3:07 Licenser_: no

3:08 defn: Licenser_: well then what is the elegant solution here, to not do it? i dont see how else to make this work

3:08 tomoj: suppose some code returns the string "[foo bar baz]"

3:08 Licenser_: that sho9uld be displayed as a string

3:08 defn: the sandbox already returns forms, you don't need to read-string them at all

3:08 defn: oh duh

3:08 tomoj: yeah, and you'll get a vector

3:08 Licenser_: just don't turn them into a string :P

3:08 tomoj: I feel like there are probably weirder examples

3:08 defn: yeah definitely, that makes perfect sense

3:10 * defn feels silly

3:10 defn: cant believe i missed that

3:10 thanks

3:11 Licenser_: ;P

3:11 well I got to go take care defn

3:11 defn: Licenser_: i owe you. thanks again

3:12 Licenser_: nah it's all in a days work :P

3:15 remleduff: defn: Not sure if you solved it another way, but you can also (binding [*read-eval* false] (read-string "#=(println \"Don't print me\")))

3:15 defn: remleduff: I think Licenser_'s solution is better. I shouldn't really be touching any of the results with read-string in the first place

3:15 but thanks for that

5:20 gerryxiao: how to get current classloader?

5:26 hoeck: gerryxiao: pick one: http://java.sun.com/javase/7/docs/api/java/lang/class-use/ClassLoader.html

5:26 sexpbot: "Uses of Class java.lang.ClassLoader (Java Platform SE 7 b66)"

5:27 hoeck: gerryxiao: eg. (ClassLoader/getSystemClassLoader)

5:27 Blkt: is there anyone who succesfully used clojure.contrib.sql?

5:27 hoeck: or (.getClassLoader (class {}))

5:28 Blkt: yes, though I don't really like it

5:29 Blkt: hoeck: me neither, though I have to ask you something about tables creation

5:29 hoeck: Blkt: oh, havent used that part of contrib sql

5:29 sids: ,(clojure.lang.RT/baseLoader)

5:29 clojurebot: #<DynamicClassLoader clojure.lang.DynamicClassLoader@3a8eac>

5:30 Blkt: hoeck: haven't you ever created a table with contrib sql?

5:31 hoeck: Blkt: only with plain strings, send over to the database with c.c.sql/do-commands

5:32 Blkt: hoeck: you normally used c.c.sql/insert-values or insert-rows function to add rows after that or you used strings as before??

5:33 hoeck: right, plain strings

5:33 Blkt: thanks for the help, I think I'll do it that way too

5:34 hoeck: I am to lazy to mess around with that part of c.c.sql, what I especially like is the abstraction c.c.sql provides about connecting to a db

6:01 LauJensen: Hi guys

6:09 AWizzArd: Hello the Lau.

6:16 kzar: So when I noticed my frame's timer was still running after I closed the window I tried adding (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE).. That kind of worked except it totally killed my Java process, how can I make it behave properly?

6:18 LauJensen: kzar: I didn't catch the preceeding discussion, but sounds like you need to override onclose

6:19 http://github.com/LauJensen/Fluid-Dynamics/blob/master/fluids.clj#L294

6:22 patrkris: #'x and (var x) is equivalent, right?

6:22 *are

6:26 kzar: LauJensen: So say if my timer ends up making my move-ball function run every few seconds, if I check for running at the top of my move-ball function it kind of works. But surely I should stop the timer from trying to run all my code? I should get rid of the cause?

6:27 LauJensen: kzar: Is the code public somewhere?

6:27 (afk 5 min)

6:27 kzar: LauJensen: no not yet I'm just throwing it all together at the mo

6:34 LauJensen: Im trying to understand your question. You've put a (when @running) in your move-ball, but instead you want it in your timer (where it should be), but thats giving you a problem ?

6:35 kzar: LauJensen: I put the (when @running in the actionPerformed section of my panel

6:35 LauJensen: Then when I close the Frame it does stop my stuff getting run, but then when I set running back to true it's all going still

6:36 LauJensen: Sounds like you need to put your predicate in another place, ping us again when the code is up somewhere

6:37 kzar: LauJensen: OK I'll paste it but it's really bad atm

6:38 LauJensen: http://paste.lisp.org/display/98709

6:40 LauJensen: Ok, and what exactly is running when you reset! running true after having closed, and what do you want to happen instead?

6:41 jowag: is it ok to put lazy seqs inside refs, or I have to realize the seq before putting it into the ref?

6:41 LauJensen: $(ref (range 10))

6:41 sexpbot: result: clojure.lang.Ref@8cc09a

6:41 jowag: e.g. (alter *x* (fn [coll] (remove pred coll)))

6:42 Chousuke: jowag: it's okay as long as the seq has no side-effects

6:43 jowag: thank you

6:46 kzar: LauJensen: Well move has a println that I can watch from *inferior-lisp*. It does stop when I close the window but when I (reset! running true) it starts printing again

6:46 LauJensen: kzar: As it should - All you're stopping is the ActionPerformed listener, that doesn't stop the mouseMoved event if you trigger that

6:47 If the program is to die once you close it, set JFRAME/EXIT_ON_CLOSE instead

6:47 The shared @running ref is helpful to stop independant thread workers, but swing will bring its own house down once you EXIT from it

6:49 kzar: LauJensen: But here's the thing that concerns me, supposing I'm making this little game and I make a change. I close the window and run (game) again. Now there's two of these processes running, maybe my ball will start moving twice as fast? Also maybe my computer will slow down if there are all these things running in the background?

6:49 LauJensen: I tried EXIT_ON_CLOSE before but it then killed Java and I had to re-start slime every time I closed the window

6:50 LauJensen: Right now, you're starting a swing app, a game but you're never destroy it (ie clean all the resources), which is a bug because you're carrying state. To clean that up, you need EXIT_ON_CLOSE and yes that does bring the repl down with it - I dont know if there's a work-around for that though

6:51 eevar2: kzar: ideally you'd calculate your ball position/movement based on the current time

6:51 LauJensen: eevar2: he's using user-input I believe

6:52 kzar: no it's all broken and not written yet

6:52 that's why I didn't want to paste it but yea you're right about the movement thing

6:52 eevar2: well, using the clock rather than updating it per frame or something like that

6:55 kzar: but what's the issue? -- @running not getting set when you close the window?

6:55 kzar: eevar2: No that part works

6:58 LauJensen: Thanks for showing me the @running thing anyway

6:58 LauJensen: np

7:00 eevar2: could also do something like (if (.isVisible frame) (recur)))))) in your drawing loop -- assuming you use immediate mode rendering

7:01 s/loop/thread

7:01 LauJensen: (future (while (.isVisible frame))) might be better, but its patch-work

7:11 jowag: I have a struct (defstruct s :a :b :c) and a existing map (def m {:a 1 :b 2}). How do I create struct from this map? (struct-map s m) is obviously not working

7:14 also (apply struct-map s m) is not doing it right

7:15 cgrand: kzar: you don't need @running in you current design, you simply need to call .stop on timer in windowClosing

7:26 jowag: ok, found it (apply struct-map s (flatten (seq m))) will do the trick

7:29 Borkdude: C-x b to switch buffer, C-x k <RET> to close a window -- in an internet borwser and then find out it doesn't work. What is this called?

7:29 s/borwser/browser

7:30 hircus: technomancy|away: ping

7:35 LauJensen: Borkdude: The disappointment of your life - same here :)

7:36 Fossi: i heard opera supports emacs keybindings at least rudimentary

7:37 using nano and constantly pressing ctrl+w to search is more annoying though

7:40 eevar2: ctrl+w sucks in netbeans as well. in most tabbed apps, actually

7:41 * eevar2 curses the day he figured using slime was a good idea ;)

7:43 _ato: Borkdude: it's called "you should be using conkeror"

7:43 http://conkeror.org/

7:43 sexpbot: "FrontPage - Conkeror"

7:51 Borkdude: _ato tnx, I installed it now. Does it to URL autocompletion? ;)

7:51 s/to/do

7:52 _ato: yeah.. I think you have to turn it on though, just a sec while I find it

7:54 url_completion_use_history = true;

7:54 Borkdude: Is there a .emacs like thing in this browser?

7:54 _ato: ~/.conkerorrc

7:54 clojurebot: I don't understand.

7:54 Chousuke: a:P

7:54 -a

7:55 Borkdude: tnx

7:58 _ato: do you have next/previous in this browser? can't find it in the tutorial

7:59 _ato: 'B' (shift b) is back, 'F' is forward

8:00 if you have a page with "Next" and "Prev" links (like a comic or reddit or something) use [ [ and ] ] (one of my favourite features, very simple but a real time saver)

8:01 mmarczyk: Conkeror! it's been ages since I used that :-)

8:01 it's been a tad immature back then, gotta give it another go :-)

8:01 _ato: C-h b will give you a list of keybindings

8:02 Borkdude: I tried it with a couple of sites, everything seems to work OK until now

8:04 ah like XKCD, that's nice

8:06 LauJensen: ?

8:10 Borkdude: _ato: if I see a couple of links on a wikipedia page, what is the handiest thing to do when I want to open one in a new buffer?

8:11 mmarczyk: C-u f

8:12 Borkdude: cool, tnx

8:12 LauJensen: wow, thats great

8:12 mmarczyk: yeah, it is :-D

8:13 Borkdude: Not to be confused with Konqueror

8:13 LauJensen: This has got to be the best news all day - an Emacs browser :)

8:13 Is there any way to embed it directly in emacs ?

8:14 Borkdude: LauJensen, yes, there is swank-conkeror... so parse the html directly with slime :P

8:15 _ato: theoretically yes, but there's not a huge amount of benefit to doing so given one speaks javascript and the elisp http://www.emacswiki.org/emacs/EmacsXembed

8:15 sexpbot: "EmacsWiki: Emacs Xembed"

8:15 _ato: there's actually an inferior javascript thing for emacs that will talk to conkeror

8:15 kind of like slime

8:15 doesn't work perfectly though

8:17 I just have a global keybinding which switches focus to the browser and another which switches focus to emacs (and a third which switches to the shell).

8:17 LauJensen: _ato: not following? I just meant C-x C-f in Emacs should allow you to browse to an url, and then it was actually conkeror doing the work

8:17 _ato: ah

8:17 yep

8:17 well

8:17 maybe not C-x C-f

8:17 LauJensen: _ato: How did u bind it to switch to C?

8:17 _ato: but there's a way to enable links to open in it

8:17 LauJensen: yea

8:17 browse-url

8:19 _ato: (setq browse-url-browser-function 'browse-url-generic browse-url-generic-program "conkeror")

8:19 I suppose

8:20 Borkdude: I recently changed it to chromium-browser, but that might change soon

8:21 LauJensen: _ato: Know of a shortcut to moving the cursor to flash

8:21 ?

8:21 _ato: heh, I'm actually using chromium at the moment, I switch back and forth between conkeror and chromium every now and then. Get sick of chromium's crap keyboard support and then get sick of Conkeror's gecko rendering being slow and memory hog

8:21 I really want conkeror with chromium rendering

8:22 and clojure scripting :p

8:22 Borkdude: _ato, can you give answer on how you switch to Conkeror with a key-binding?

8:22 and back from Conkeror to Emacs

8:22 _ato: LauJensen: nope I never found a good solution to flash, flash is one of the annoying things in conkeror

8:22 LauJensen: (.replaceAll "in conkeror" "")

8:23 _ato: Borkdude: I use the Sawfish window manager

8:23 Borkdude: ah, so it isn't an Emacs key-binding but a wm keybinding

8:24 mmarczyk: _ato: I almost believed you've decribed an actual perfect browser for a sec

8:24 as it is, I share your dream...

8:24 Borkdude: yes, _ato... I do to, but then Emacs with Clojure scripting is also part of that dream?

8:26 _ato: so with sawfish I have this in config, which I probably just stole from _mst's sawfish config: http://gist.github.com/388039

8:26 mmarczyk: it would have been cool if the Guile people had rewritten Emacs, like, 15 years ago -- we'd all have settled into a nice Scheme-based editor by now :-(

8:26 _ato: and the same for terminal, browser etc

8:27 I started writing a Clojure browser with QT Jambi actually

8:27 but QT Jambi's webkit version is old, and it's slow :(

8:28 and QT Jambi is no longer supported by Trolltech so it's kind of a dead end that way too

8:28 LauJensen: _ato: Unless you find a sponsor :)

8:28 It was sooooo close to _really_ good

8:28 defn: any suggestions on making it more obvious that you can click on an example to see it's result? http://getclojure.org:8080/examples/concat

8:28 sexpbot: "concat"

8:29 Raynes: sexpbot: I appreciate the stating of the obvious there.

8:29 defn: I've added some CSS to give you a different cursor when you mousover, but not all browsers play nice.

8:30 mmarczyk: defn: how about adding a notice at the top saying "you can click on an example to see its result"? :-)

8:30 defn: mmarczyk: hehe, yes but that's so...ugly :)

8:30 mmarczyk: nice page, btw

8:30 defn: mmarczyk: you can do /examples/anyfunction to see examples of that function

8:31 Raynes: So is people doing "This stuff sucks" and then 30 days later, accidentally clicking on an example and being like "Who was the idiot who designed this page?"

8:31 _ato: I guess you need some sort of arrowy-expandy button thingy

8:31 mmarczyk: 2. (class (concat 1 2)) ?

8:31 defn: yeah _ato i was thinking something along those lines maybe

8:31 mmarczyk: that's broken :-)

8:31 defn: ,(class (concat 1 2))

8:31 clojurebot: clojure.lang.LazySeq

8:31 defn: no it's not :)

8:31 _ato: or alterntively just always show the result :p

8:31 chouser: defn: a link to the left of the bottom of each snippet (under the number)?

8:32 mmarczyk: ,(concat 1 2)

8:32 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

8:32 Raynes: $(class (concat 1 2))

8:32 sexpbot: result: class clojure.lang.LazySeq

8:32 zmila: defn, add attribute title='click the example text to evaluate and see the result' to the enclosing <div>

8:32 defn: chouser: a la the labrepl -- yeah i think that's a good way to go

8:32 LauJensen: Raynes: I got a message via your bot the other day, saying that the s/x/y feature was implemented, subsequently I tried it out and it FAILED

8:32 mmarczyk: it's lazy, so won't break immediately, but it would help to use fully working examples


8:32 sexpbot: Command not found. No entiendo lo que estás diciendo.

8:33 mmarczyk: indeed

8:33 Raynes: Haha.

8:33 s/indeed/omg/

8:33 sexpbot: Haha.

8:33 mmarczyk: defn: except of course where it's supposed to break

8:33 defn: mmarczyk: eventually, someday, way way in the future, in a different world, i hope to add the ability to actually vote up or vote down an example

8:33 Raynes: LauJensen: How did it fail, exactly?

8:33 mmarczyk: defn: you could move the numbers to the left of the code boxes

8:33 LauJensen: in the way that it didn't react

8:33 _ato: Where's adblock activated in conkeror?

8:33 Raynes: LauJensen: Well, as you can see, it works now. :)

8:34 s/Well/indeed/

8:34 sexpbot: LauJensen: indeed, as you can see, it works now. :)

8:34 mmarczyk: defn: and display the "click for result" notice below the HR in a nice subdued grey

8:34 Borkdude: defn: can users contribute their examples?

8:34 defn: mmarczyk: cool advice

8:34 LauJensen: s/adblock/adjure/

8:34 sexpbot: mmarczyk: cool advice

8:34 _ato: LauJensen: once you've installed M-x adblockplus-settings

8:34 defn: Borkdude: (this (is (an (example)))) <---submitted

8:34 mmarczyk: LauJensen: apparently you've just caught a sexpbot bug :-)

8:34 defn: it wont run in the sandbox of course, but it will be submitted

8:35 Raynes: LauJensen: I guess Erik didn't make that little special case user-based. I'll ask him to do it or do it myself later.

8:35 mmarczyk: defn: how about putting a bot here, on #clojure, to accept examples

8:35 Borkdude: defn: it reads examples from #clojure? where I can see the example you just told me?

8:35 defn: mmarczyk: already in progress

8:35 mmarczyk: defn: which we could submit as interesting stuff comes up in conversations :-)

8:35 Raynes: mmarczyk: Already in progress, and it uses Irclj. ;)

8:35 mmarczyk: defn: oh, great :-)

8:35 cool!

8:35 _ato: ,(concat "hello" "_ato")

8:35 clojurebot: (\h \e \l \l \o \_ \a \t \o)

8:36 Raynes: defn: If it's really important, I'll get some logging into Irclj quickly. I've been putting it off.

8:36 defn: _ato: right now i dont have the continuous update thing running on my server, but it will work very soon

8:36 _ato: cool

8:36 defn: Raynes: not really important, in fact i think I can do pretty much everything i need with what currently exists without the logging functionality

8:37 Raynes: I think that defn running a walton-bot would be better than sexpbot running it. At least, unless it suddenly stops taking a month to parse logs. :p

8:37 defn: basically :on-message (add-sexp-to-ref (hunt-for-sexp message))

8:37 then every hour or so use stupiddb to serialize it

8:37 zmila: defn, why such order of examples? mix of simple ones and complicated. can you sort them?

8:37 Raynes: sexpbot has a walton plugin, but I keep it disabled because it tends to screw stuff up.

8:38 defn: zmila: also a feature id really love to add, but there have been some...shall i say...hiccups -- it's definitely the plan to have filtering functionality though

8:39 also, as long as i have everyone's attention: http://github.com/defn/walton "patches welcome"

8:39 _ato: heh, could use that golf scoring scheme somebody came up with on the mailing list, symbol counts and such to score complexity and then sort by that, so the examples get progressively more complex

8:39 defn: see the wiki for stuff on the todo list

8:39 _ato: ooo! link!

8:40 im not a golfer, but incremental complexity scoring thingamajig sounds cool :)

8:40 Borkdude: defn: a voting mechanism a la stackoverflow would be really cool

8:40 defn: Borkdude: you're seeing the forest now! that's exactly what i intend to build

8:40 _ato: google groups search is so crap... hmm

8:40 defn: something a lot like stackoverflow

8:40 only more code-specific

8:41 chouser: http://groups.google.com/group/clojure/browse_thread/thread/c3bbffe417fc6fcb/bf5d1ff5a943c295

8:41 defn: id like to spin off the code and allow people to write parsers for other languages and build a python, ruby, etc. version of the site

8:41 Borkdude: defn: how do you filter our crap examples, or erroneous ones like when somebody asks a question and first proposed faulty code?

8:42 s/our/out

8:42 defn: Borkdude: i use Licenser and Rayne's work -- the clj-sandbox

8:42 it runs code in a sandbox and if they run, that's what you see

8:42 bsteuber: hm, I still can't get swank-clojure to work with the new meta syntax - is there something eval'ed that doesn't come from swank-clojure itself, like clojure-mode etc.?

8:43 Borkdude: so if it runs, it gets read into the site?

8:43 defn: yeah, not continuously yet, but it gets updated with new logs every couple days

8:43 Borkdude: I see. Good luck with that, it's very cool imho

8:43 defn: so: (first [1 2 3 4]) will show up on there if it's not a duplicate

8:43 just for me having written it here

8:44 chouser: defn: I think this may be the "final" implementation: http://groups.google.com/group/clojure/msg/bae1846d558ad038

8:44 defn: chouser: awesome. thanks

8:45 wlangstroth: defn: are we discussing walton?

8:45 defn: wlangstroth: indeed

8:45 wlangstroth: I've used it a bunch - I love the new look

8:45 defn: wlangstroth: thanks man. my friend did that for me. he's working on a front page

8:46 * Raynes blushes because he was mentioned.

8:46 * Raynes goes back to his work on sexpbot.

8:47 wlangstroth: defn: is there a way to force it towards certain results? For instance, when I do http://getclojure.org:8080/examples/for it gives me for *and* format

8:47 sexpbot: "for"

8:47 wlangstroth: any way around that?

8:47 * Raynes adds getclojure to the list of links to ignore.

8:48 defn: it can be quite fun when someone asks, "how do i reverse a map {:a 3 :b 4} and sorts by value" or something like that, or a question about destructuing -- doing /examples/let is pretty interesting to see how powerful destructuring can be

8:48 wlangstroth: im working on some filtering that will let you be specific to symbols instead of strings

8:48 wlangstroth: nice

8:49 defn: wlangstroth: really glad you like it :)

8:50 wlangstroth: submit a feature suggestion via github issues if you have the time

8:50 it keeps things visible for me -- lots of ideas on functionality, but only so much time and all that

8:51 wlangstroth: okay, np

8:54 Borkdude: one paredit question: if I have (foo "bar" "baz"|) how do I swap "bar" and "baz"?

8:55 mmarczyk: C-M-t between "bar" and "baz"

8:56 defn: test

8:57 Borkdude: tnx.., although Gnome opens a terminal window for me now, have to fix that ;)

8:57 _ato: defn: have you heard of the squeak (smalltalk) method finder?

8:57 wlangstroth: Is anyone clear on why there's a next and rest? I was under the impression that ISeq was always meant to return nil if empty (like next does). Is rest a special exception to that?

8:58 Chousuke: wlangstroth: rest is the norm

8:58 defn: _ato: i havent

8:58 mmarczyk: wlangstroth: that used to be true, but hasn't been for a long time now

8:58 wlangstroth: mmarczyk: okay, that's what I figured it was - thanks

8:58 _ato: defn: someone mentioned that here before (or on the list) and it's a really cool idea that you might like for walton as well... basically..

8:59 defn: it's for finding a function when you don't know it's name. You give it some arguments and an expected result and it gives you back a function name

8:59 so you'd enter: 2 3 => 5

8:59 and it'd reply: (+ 2 3) => 5

9:00 presumably you could implement it by just brute-force trying a big list of pure functions

9:00 and try it with the arguments reordered too, as the user may not know the right order for them

9:00 defn: _ato: i started working on something like that actually

9:00 called whatfn -- i havent really touched it, but it's inspired by _why's "what_method?"

9:00 (what? [1 2 3] [3 2 1])

9:01 => (reverse [1 2 3])

9:01 your version seems like it might be easier

9:02 it'd be cool to say (what? ["a" "b" "c"] ["B" "C" "A"])

9:02 Raynes: defn: I can work with that.

9:02 _ato: haha, I looked at your github and it's like: usage: (what? ...) and I think awesome! he's already done it

9:02 http://github.com/defn/whatfn/blob/master/src/whatfn/core.clj

9:02 but the clj was bare :(

9:02 Raynes: defn: Isn't his version the exact same "easy" version I proposed when we were talking about it the other night? ;)

9:03 _ato: ;-)

9:03 defn: Raynes: _ato haha i became a bit obsessed with making it better and better before i even started

9:03 i want it to chain functions and do all sorts of crazy inference engine AI type stuff

9:03 but your version is so much more doable

9:04 mmarczyk: ...then at some point you could say (what? --a-huge-number--) and get back (nth-mersenne-prime 53) ;-)

9:04 _ato: haha

9:04 defn: :)

9:04 it'd be filled with easter eggs, for sure

9:04 see: wolfram alpha :)

9:04 wlangstroth: The idea of making a function look-up the most powerful tool in the universe is hilarious.

9:06 defn: wolfram alpha: please promise to solve all my problems and then do a mediocre job across the board

9:07 Borkdude: Twitter is the Wolfram Alpha for questions that do not have numerical answers

9:07 wlangstroth: They really missed the boat on some funny UI features. For instance, with anything the search can't answer, it should return "Thinking ..." or "Processing ..."

9:07 (and never actually answer the question)

9:07 defn: wlangstroth: hahaha -- that'd be great

9:08 wlangstroth: People would likely figure that it was thinking REALLY hard, or that they broke it.

9:08 Borkdude: wlangstroth: it would be great if it could decide whether the problem is indecidable or not

9:08 wlangstroth: Borkdude: you mean for things like unsolvable differential equations?

9:08 defn: "I'm stuck. Sent email to Stephen Hawking..."

9:09 "You've heard of Fermat's last theorem, right?"

9:09 an infinite number of fun responses :)

9:09 wlangstroth: defn: I like "currently on the phone with Stephen Hawking". Imagine how that conversation would sound.

9:09 defn: wlangstroth: brilliant. :)

9:10 "Using second life line."

9:10 wlangstroth: haha

9:10 (what? "life")

9:10 defn: => 42

9:10 wlangstroth: => "Contacting Richard Dawkins and the Dalai Lama"

9:11 defn: hahahahaha

9:11 => "Daniel Dennett may know this one! Seriously!"

9:11 wlangstroth: That would be for (what? "consciousness")

9:11 Borkdude: "Have you thought about this yourself already?"

9:11 "RTFM"

9:12 wlangstroth: "Please hold ... accessing Daniel Dennett"

9:12 defn: => "Contacting Christopher Hitchens for a pithy response..."

9:12 Borkdude: "Gathering responses from Twitter..."

9:12 defn: actually, what would be great is if it can't answer the quesiton, it just gets a completely random twitter message about Justin Bieber

9:13 i think that'd really send the whole thing home

9:13 wlangstroth: haha

9:13 defn: Or how about this: it presents a dialog: "Is this your IP?" [Yes/No]

9:13 "Stay where you are."

9:13 wlangstroth: I haven't even seen this Bieber kid, but someone told me he's causing teenage girls to trample each other

9:14 defn: it's a bit of pop culture I'm not so happy to admit I'm aware of

9:14 my little brother tweets exclusively about his hatred for the boy -- more important things to be chatting about i say, but to each his own

9:16 wlangstroth: true nuff. Here's another open-ended question: would I be stepping on anybody's toes if I wrote more detailed documentation for clojure core?

9:17 defn: wlangstroth: i don't think so.. i mean i look at it like this: even if you are duplicating effort, it's a fantastic way to learn more for yourself, and provide content for others

9:17 i say have a go at it

9:18 Borkdude: defn, it would be great to combine the most useful (upvoted...) examples into the clojure documentation

9:18 wlangstroth: I'm already doing it to learn, but I guess we'll see if anyone's into it once I've finished

9:19 defn: Borkdude: maybe at some point that could happen, but that'd largely be at rich and others' request/authorization

9:19 wlangstroth: Borkdude: the examples are exactly what I was thinking about. Take the example for "for":

9:19 ,(doc for)

9:19 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test. (

9:20 defn: yeah...oof...

9:20 Borkdude: defn: wlangstroth: maybe you can have a contrib like approach to the documentation, when it will be used enough it can end up in the official documentation at some point?

9:20 defn: i mean maybe im a simpleton, but that text just does not immediately say to me: "here's how you use 'for'", which ought to be the aim of such a docstring

9:21 Borkdude: defn: amen

9:21 wlangstroth: We'll try that. I don't think Rich has my CA yet. I only mailed it a couple of weeks ago, though.

9:21 defn: i suppose one problem is that docstrings are not meant to be so long-winded

9:21 it might be nice to have a bit of meta that points to a good example

9:21 Blkt: hello everyone

9:21 Borkdude: defn: wlangstroth: I also miss "also see ..." in the docs

9:21 wlangstroth: defn: exactly - I'm not suggesting a replacement (except for "for", maybe, because that one completely confused me as a beginner)

9:22 _ato: heh

9:22 defn: yeah, same here -- im still a bit iffy on using it

9:22 _ato: it chopped off the useful part of that docstring:

9:22 defn: im pretty much a beginner though

9:22 _ato: (take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))

9:22 wlangstroth: Borkdude: that's a bit tougher to do, though, and I think it's just Tom who's working on the docs, so his hands are full

9:23 defn: the thing with clojure is than 6/10 times viewing the actual source is more helpful than the docstring

9:23 the docstring itself is a very well thought out version of the reasoning that exists in the code

9:23 and once you see the code you say "ahhhh!"

9:23 Borkdude: defn: how can I view the source in emacs btw?

9:23 defn: but for people not familiar with FP it is very weird at first

9:23 Borkdude: do you use slime?

9:23 Borkdude: defn: yes

9:24 chouser: yeah, I use 'source' about as much as I do 'doc' for most things

9:24 not including gen-class

9:24 defn: put your pointer at (foo|)

9:24 and hit M-.

9:24 (zipmap|) for instance

9:24 where the | is your pointer

9:24 hit M-, to get back to your repl

9:25 Borkdude: defn: no context for finding locations.

9:25 I guess I have to use the clojure-src.jar or smth?

9:25 defn: hmm, weird

9:25 im just using M-x slime with all of the ELPA packages, slime-repl, slime, clojure-mode, swank-clojure

9:25 Borkdude: defn sorry I dit C-M-.

9:25 did

9:25 it works

9:26 defn: cool -- that's insanely helpful

9:26 it should be one of the first things people learn once they're up and running with a slime repl

9:26 rhickey: want serializable data structures in 1.2? Move this patch forward now: https://www.assembla.com/spaces/clojure/tickets/281-make-more-datastructures-serializable

9:26 defn: took me a month or two :X

9:26 sexpbot: "#281 - Make more datastructures serializable (Test) | Clojure | Assembla"

9:27 peregrine81: unless you use Vim!

9:28 defn: vim and emacs will i think eventually fall out of favor when IDE support really gets rolling. there are a lot of fantastic projects that exist right now, but i think it's still an argument as to whether they beat emacs + slime + paredit yet

9:29 a nice refactoring browser would squash anything vim or emacs has to offer

9:29 Borkdude: defn: which IDE support is the best up till now you think?

9:29 peregrine81: defn: agreed but many people still use emacs or vi for every day programming.

9:29 defn: Borkdude: i dont know enough, but i thought enclojure was quite good

9:29 LauJensen: defn: You're wrong and speaking out of ignorance

9:29 peregrine81: Counterclockwise was very good.

9:29 zmila: there is no argument for those who has 6+ years using Eclipse, but only two or three times runned emacs

9:30 Borkdude: defn: I started ClojureBox in the beginning, but I had some classpath problems

9:30 wlangstroth: LauJensen: you always enter with a bang, I'll give you that

9:30 Borkdude: defn: then I started using Eclipse + CounterClockwise, but the obliged paredit made me feel sick, because I didn't know that yet

9:30 LauJensen: Not meant harshly mind you :)

9:30 Borkdude: So then I switched to emacs, using elpa swank clojure, and it's the best I've used so far

9:31 wlangstroth: LauJensen: I think everyone is familiar with your love of emacs

9:31 defn: LauJensen: maybe-- i won't try and act like i know everything about emacs, vim, enclojure, etc. I was swayed by Uncle Bob's comments on Smalltalk, refactoring browsers, etc.

9:32 Borkdude: LauJensen, do you do Java development in Emacs, without any other IDE?

9:32 defn: JDE is pretty good for emacs

9:33 LauJensen: defn: Emacs big win is integration. You have fantastic editing tools, which makes you so much faster than the guys sitting in these big IDEs, you have IRC, Gist, Git, SVN, Hg integration at your fingertips, testing is built in, organizing/planning is built in - You can start Emacs in the morning and not close it till you release, because literally everything is in there - the payoff is effectiveness like you wouldn't believe

9:33 defn: familiarity will always play a role. i don't know. I love emacs and have no good reason to switch, but I have faith that the proper combination of features could make me switch.

9:34 LauJensen: yeah but one thing i love one moment and hate the next with emacs: choice

9:34 there are too many damned choices. it's distracting

9:34 LauJensen: huh?

9:34 defn: i spent 8% of my time in emacs configuring emacs

9:34 LauJensen: Odd, I spend like 0.01% :)

9:34 Borkdude: defn: I was thinking how touch screens would change the need of remembering key combinations for paredit. It's much more intuitive to just select some sexp elements and move them around with your finger maybe?

9:35 defn: LauJensen: im just suggesting that choice can sometimes be a problem. it's something i value in emacs one minute, and find distracting the next.

9:35 Raynes: Speaking of Git, is there a way to make Magit pull from a different repository than the default one? Like, you can change where it pushes with a prefix argument.

9:35 LauJensen: defn: Sure I understand. Like comparing Ubuntu to Arch. Arch takes a lot longer to set up initially, but once you have a working config, its trail blazing

9:35 licoresse: defn: I agree, (choice)

9:36 defn: LauJensen: but im never finished setting up emacs. there's always one more tweak, one more hotkey i think of, one more function i should write.

9:36 sometimes i dont want to know how much power i have

9:36 LauJensen: hehe

9:36 defn: LauJensen: that being said i am 100% happy with emacs and wouldn't switch for all the tea in china, as they say

9:37 LauJensen: All I can say is, that its not been a problem for me, but then maybe Emacs isn't for everybody. I just dont think it's going to be blown out of the water anytime soon

9:37 wlangstroth: vim and emacs are like different languages: are we going to argue about whether English or German is a "better" language?

9:37 LauJensen: defn: And me on the other hand, I would switch for all the tea in china :)

9:37 defn: LauJensen: yeah i will agree, not blown out of the water, but you just..nefver..know.. :)

9:37 LauJensen: haha

9:37 LauJensen: wlangstroth: no, German is clearly better

9:38 defn: wlangstroth: i dont think there was ever a vim/emacs duel going on here

9:38 it's what works for you

9:38 wlangstroth: haha

9:38 Borkdude: Why would you need vi when you have a vi mode for Emacs? ;)

9:38 wlangstroth: so is there actually a large demand for serialized data structures in clojure?

9:39 I didn't see anyone jumping when Rich posted that

9:39 Borkdude: LauJensen: do you use Arch btw?

9:40 defn: wlangstroth: it'd be nice. im using them now. since refs are db-like in their concurrency semantics I find the idea of serializing structures quite appealing.

9:41 as i understand it you can serialize structures earlier than 1.2 but maybe im misunderstanding something

9:43 LauJensen: Borkdude: Yes its installed, although Ubuntu is my main OS atm until I get my partitions sortedo ut

9:43 wlangstroth: defn: I'm having difficulty seeing the added value, but I might be misunderstanding Java serialization.

9:46 _ato: I think it might be useful for some of those distributed computing libraries

9:46 sending objects across the network seamlessly etc

9:47 I don't know enough about java's serialization to be able to fix that patch

9:48 if it just needs reformatting then no problem, it applies cleanly for me

9:49 wlangstroth: _ato: the first diff to the patch just added "Serializable" to each of the data structures, I think (which is all you're supposed to do in Java, but clojure already has the immutable structures ... I'll obviously have to research this more)

9:53 _ato: do you mean other concurrency libraries in Java?

9:53 cemerick: rhickey: regarding 281 (serialization) -- by "moving it forward", do you mean making the patch apply, or are there any outstanding technical issue?

9:53 issues*

9:55 rhickey: cemerick: whichever. I'm not sure what Brian meant by this: http://groups.google.com/group/clojure/msg/e8a9c7392bd82fd6

9:58 cemerick: rhickey: From his comments on the ticket, it sounds like he was concerned about transients. Either way, shouldn't be too difficult to skin that cat so that reasonable things happen (e.g. throw an exception when attempting to serialize a transient, or maybe (probably not) cons up a persistent copy, and serialize that).

9:59 rhickey: cemerick: transients are non-serializable, please

9:59 cemerick: sure

10:00 rhickey: I can claim that issue, if Brian's not going to get it in in time. Is there a window you have in mind for the RC?

10:00 rhickey: cemerick: great! ASAP

10:01 cemerick: If he was worrying about encountering an inner node that was under modification by a transient while traversing from a persistent root- that can't happen. And since the transient roots are different type, making them non-Serializable is sufficient

10:03 cemerick: rhickey: OK; in any case, I'll be adding a metric ton of tests to ensure that the right things happen. This is one of those things that, if a regression slips through, one doesn't find out about it until the regression is bound to cause serious problems.

10:04 rhickey: cemerick: It would be great to see this in 1.2, and in the hands of an interested party :)

10:11 AWizzArd: Are there plans to have deftype/defrecord produce no constructor, so that users will be forced to use my provided factory fn?

10:12 chouser: AWizzArd: how would your factory fn be written if there were not constructor?

10:14 * Raynes is so tired of reflection warnings. x_x

10:14 chouser: Raynes: just turn them off

10:14 Raynes: chouser: I can't. I've tried in a thousand different ways.

10:14 I guess a library or something that I require is turning them on.

10:14 chouser: :-(

10:15 Raynes: I can set it with binding, set!, anything. They still show. :|

10:15 defn: ahh, that's mean of them

10:15 chouser: have you tried using set! immediately after 'require'ing all your libs?

10:15 Raynes: No, I didn't try that. I assumed that it was happening when the libs were required.

10:16 chouser: yeah, it may be

10:16 Raynes: As soon as they are required, around 30 reflection warnings fly my way.

10:16 chouser: I'm very sorry. sounds horrible.

10:16 Raynes: I'm tempted to hunt down which library is doing it and then beg for them to shut it off.

10:17 defn: Raynes: is this in irclj?

10:17 ill hunt down the bandit :)

10:17 Raynes: http://gist.github.com/388130

10:17 defn: No, it's in sexpbot.

10:18 That's more than 30.

10:18 :o

10:18 defn: Raynes: just open a new repl and (use '...) each of them one by one

10:18 Raynes: Good idea.

10:18 I'll do that in a moment.

10:20 _ato: or: mkdir /tmp/blah; cd /tmp/blah; for lib in ~/src/sexpbot/lib/*.jar; do unzip $lib; done; grep -R 'warn-on-reflection' .

10:20 hiredman: pfft

10:20 Raynes: Found it.

10:20 clj-apache-http

10:20 Bad news, man.

10:20 hiredman: use finf

10:20 use find

10:21 _ato: hiredman: find inside jars? or you mean find to filter to clj files before grepping?

10:21 AWizzArd: chouser: the factory could be inside the defrecord form

10:22 So the defrecord could produce a private constructor or something like that.

10:22 chouser: AWizzArd: ah, I see. I haven't heard of any plans like that.

10:22 _ato: http://meshy.org/~ato/clojure-group-stats/

10:22 sexpbot: "Clojure group subscriber count graph"

10:22 _ato: seems it gains 4 or 5 subscribers a day

10:23 AWizzArd: chouser: this could potentially be a protection from data corruption.

10:23 * Raynes forks clj-apache-http and pushes a version that doesn't turn that nasty warn-on-reflection on

10:33 Raynes: For great justice! I've done it! No more reflection warnings.

10:39 Borkdude: Ah, the kill-other-buffers in Conkeror is really what I need

10:41 LauJensen: Borkdude: hotkey ?

10:41 Borkdude: dunno, I just do M-x

10:41 cemerick: rhickey: are you aware of the prependss type in core.clj?

10:41 LauJensen: Borkdude: its not bound by default I see

10:41 Borkdude: M-x k tab o tab <RET>

10:43 one more thing I need to find out is how to give the focus back to the window, so it listens to "g", "c" etc, when I am in GTalk inside Gmail

10:43 without using the mouse that is

10:46 ah, escape

10:46 damn this browser is cool ;)

10:50 LauJensen: its super fantastic incredible and outstanding

10:57 Raynes: Whoa whoa whoa! Who uses GTalk? ;o

10:57 Borkdude: Raynes: I do, smth wrong? :)

10:58 Raynes: Totally not. I just didn't realize people actually used that.

10:58 :o

11:00 Borkdude: Raynes: what do you use

11:00 Raynes: I use IRC.

11:00 :p

11:00 Borkdude: Me 2 ;)

11:00 defn: I use gtalk, irc, aim -- pidgin makes the whole maze of chat networks pretty manageable

11:00 but irc for all "srs bsns" of course

11:00 Raynes: I use pidgin for MSN.

11:01 But I haven't been using it recently, because all the interesting people are here or in #clojure-casual.

11:07 LauJensen: if I could, I would use Conkeror for everything :)

11:12 rhickey: cemerick: what about prependss ?

11:14 cemerick: rhickey: I figured it was a typo?

11:15 rhickey: ss = symbol/seq

11:15 just an internal fn Steve used for load stuff

11:15 wthidden: Q: what is the difference between load-file and load-reader?

11:18 cemerick: rhickey: FYI, the existing patches on 281 are not comprehensive.

11:18 rhickey: cemerick: ok

11:19 what's missing?

11:20 bhunji: I love Lisp, is there love in Clojure?

11:20 Raynes: We're all like a bunch of hippies in here.

11:20 * Raynes loves everybody. Especially defn <3.

11:21 cemerick: rhickey: PAMap and PQueue so far.

11:21 bhunji: Raynes: thats good loving mon

11:21 cemerick: rhickey: Any objections to putting Serializable on the abstract classes, as opposed to scatting it across all the concrete impls?

11:21 scattering*

11:22 rhickey: cemerick: any drawbacks?

11:24 cemerick: rhickey: Not that I can tell. Maybe the false implication that any derivee will get serialization for free, when they'd probably have inner classes they'd still have to mark appropriately.

11:24 Third parties should mostly be using the interfaces, anyway.

11:24 rhickey: cemerick: you'd just need to audit that all derivees in Clojure itself are in fact serializable

11:27 cemerick: rhickey: I'll root around. Aside from transients (which appear to have their own class hierarchy anyway), any other candidates for exclusion off the top of your head?

11:28 rhickey: cemerick: exclusion via what mechanism? one problem with Serializable as a mixin tag interface is you can't get rid of it

11:29 cemerick: rhickey: If the vast majority of derivees are rightly serializable, the outliers can add a writeObject method that throws an exception.

11:29 rhickey: cemerick: sounds icky, is that convention?

11:30 cemerick: rhickey: it would be icky. That's definitely the easiest route.

11:31 rhickey: cemerick: how hard is the hard route, really?

11:31 cemerick: There isn't much convention in this area, I don't think -- I've already spent more time thinking about serialization this morning than most devs think about it their entire career.

11:31 </snark>

11:31 rhickey: heh

11:32 cemerick: The hard route is for the outlier in the hierarchy to implement Externalizable, which carries two methods (read/write), and is preferred over the default ObjectOutputStream regime.

11:33 rhickey: cemerick: my preference it to put it on the concrete classes. OTOH, one of the built-in icky things is that any base that has data must be Serializable, so Obj would bring it in in a lot of cases

11:34 cemerick: but Externalizable isn't for opting out, it's for customizing, right?

11:34 cemerick: rhickey: right, one reason why I figured we should just put it on the abstracts.

11:34 ostensibly, but nothing keeping you from tossing an exception there, either. :-P

11:35 rhickey: my long-term strategy is to get rid of Obj, but it seems to me the 'hard' alternative is to mark the concrete leaves Serializable

11:36 cemerick: Moving "Serializable" strings around isn't a big deal, just tedious and error-prone.

11:36 * cemerick isn't sure which point he was trying to make there

11:36 rhickey: all derivees of ASeq will get it from there

11:37 cemerick: it's more error prone to inherit Serializable and forget to defeat it

11:37 cemerick: insofar as Obj (or its successor)'s derivees are values, then they *should* be serializable.

11:38 rhickey: I'd say, take waht you get for free from Obj, then put the rest on the concretes

11:38 cemerick: OK

11:39 There needs to be a large warning that default Serialization is *not* for long-term storage.

11:39 stuartsierra: Isn't that a given with Java serialization?

11:39 cemerick: At least until Obj implements Externalizable, and delegates to print-dup or something.

11:39 stuartsierra: decidedly not

11:39 stuartsierra: oh

11:39 rhickey: cemerick: still need to audit ASeq derivees to ensure all are truly Serializable or fault as you described

11:40 cemerick: Yeah

11:40 If I find any issues, we'll still have to use the writeObject trapdoor.

11:41 rhickey: cemerick: right, ok for now, and we can remove when Obj goes away

11:42 cemerick: stuartsierra: just think of all those in-process databases that allow you to quick-and-easy persist any object.

11:42 AWizzArd: cemerick: when you say that default serialization is not for long-term storage, do you then mean a) objects such as defrecords from Clojure, or b) jvm objects in general?

11:42 rhickey: cemerick: should move Serializable from AFn to AFunction I think?

11:43 stuartsierra: cemerick: I thought they all relied on schema mappings, like Hibernate

11:43 cemerick: rhickey: er, yes, but why is AFn Serializable to begin with?

11:44 * cemerick vaguely recalls some discussion of this a long time ago

11:45 rhickey: cemerick: used to have data, and is base of some data structures

11:46 cemerick: AWizzArd: c) objects whose classes are apt to change in the future

11:46 rhickey: cemerick: but fns should serialize ok

11:47 cemerick: rhickey: how much do they capture?

11:47 stuartsierra: Many do, many don't

11:47 rhickey: cemerick: the things they use. Obviously if they close over something non-serializable that won't work, but otherwise ok

11:48 cemerick: Oh, I remember this now.

11:48 Along with a discussion about equality of fns.

11:49 rhickey: the latter is a philosophical discussion we should avoid at present

11:49 cemerick: yes

11:49 replaca: rhickey: I saw you scheduled the defmulti ticket. Do you want a ticket and patch for the corresponding declare issue as well?

11:50 rhickey: replaca: sure, thanks. I haven't had time to dig into that yet

11:50 replaca: rhickey: ok, cool. I have no idea if my approach is the right one or not, so make sure you audit! :-)

11:51 rhickey: replaca: ok.

11:51 bbl

11:54 cemerick: ooh, clojure's build stomped on my pom.xml. Nice! :-D

11:59 ouch:

11:59 ,(= (into clojure.lang.PersistentQueue/EMPTY (range 5)) (into clojure.lang.PersistentQueue/EMPTY (range 5)))

11:59 clojurebot: java.lang.NullPointerException

11:59 stuartsierra: cemerick: Ant eats POMs for breakfast.

12:00 cemerick: stuartsierra: my carefully-crafted POMs, in particular. Thank goodness for local IDE history.

12:01 stuartsierra: You need you POMs set in stone, to make them POM-o-granites.

12:04 _brian2_: noob question> can someone show me how to call this java constructor which uses a cast in clojure : http://clojure.pastebin.com/yFXbEKSQ

12:05 stuartsierra: _brian2_: just call it, no casting needed

12:05 _brian2_: ok, thnks

12:05 stuartsierra: np

12:06 AWizzArd: _brian2_: (let [compiled-classifier (AbstractExternalizable/compile classifier)] ...)

12:06 _brian2_: ok, thnks

12:06 mmarczyk: ,(.equiv clojure.lang.PersistentQueue/EMPTY clojure.lang.PersistentQueue/EMPTY)

12:06 clojurebot: java.lang.NullPointerException

12:13 _brian2_: AWizzArd: going back to my previous question, is this equivelant? (def compiledClassifier (. AbstractExternalizable compile classifier))

12:25 cemerick: mmarczyk: I've got a patch for that now.

12:25 mmarczyk: cemerick: oh cool, can't wait to read it :-)

12:26 cemerick: Not much to it, I think it was just a copy/paste issue.

12:27 mmarczyk: equals has the same problem

12:27 cemerick: yup

12:31 Moominpapa: Hi, could someone help a newbie get Compojure working under Windows?

12:31 I've got it built, but I'm trying to build a .ps1 file to run "Hello World"

12:32 cemerick: rhickey: you'll want this in 1.2: https://www.assembla.com/spaces/clojure/tickets/331

12:32 sexpbot: "#331 - Fix PersistentQueue equality methods (New) | Clojure | Assembla"

12:33 lrenn: So, I'm trying to use clojure from an ant task. This means clojure isn't on the system classpath, but is in the class.getClassLoader. I can reference clojure but RT.init fails since it's trying to use the system classloader. I can get around this by Thead.currentThread().setContextClassLoader(this.class.getClassLoader())

12:34 However, I'd like to avoid using any java, and write my tasks uses clojure and gen-class. Is there anyway to this without java?

12:38 chouser: lrenn: you might be able to aot-compile some clojure to do that kind of setup for youe

12:38 you

12:40 lrenn: chouser: the tasks themselves are aot compiled. Oddly enough, this all worked fine in clojure 1.0.

12:41 1.0, worked fine with pure clojure and gen-class. 1.1.0, can't find clojure/core.clj during RT.init.

12:41 _brian2_: Moominpapa: as a fellow noob, I suggest not bothering with windows, it's an extra level of complication, atleast go with cygwin

12:42 Moominpapa: Yeah, I spent several days on Ubuntu in VMware

12:42 Which worked, but was slower than treacle.

12:43 _brian2_: yea , you need a lot of memory for that

12:43 Moominpapa: This was my next shot.

12:43 Well, I've got 8G.

12:43 _brian2_: hmm

12:43 Moominpapa: So maybe I just need to assign more to the instance.

12:43 _brian2_: dont know

12:43 Moominpapa: Nor do I :)

12:44 It's annoying, I've solved everything else, including how to get lein to work on Windows (that was painful)

12:44 Maybe I'll try cygwin :)

12:44 _brian2_: i suggest cygwin, its better than vmware route for this kind of thing

12:45 vmware is great for testing cluster's etc

12:46 Moominpapa: Annoying, it was really easy to get working (barring a keyboard issue) but the performance wasn't really usable.

12:46 Query:

12:47 You still use Windows Java with Cygwin, or is there a special version?

12:47 _brian2_: no

12:47 everything is more or less transparent

12:48 no special version of anyhthing

12:48 Moominpapa: That sounds promising.

12:48 rsh: do futures run on a fixed size thread pool?

12:49 chouser: no

12:49 blocking in a future is ok

12:52 Blkt: is there a way to source-level debug Clojure?

12:54 chouser: Blkt: many java debuggers work, such as jswat and the one in netbeans

12:55 Blkt: chouser: no way to have something like that with Emacs?

12:55 chouser: dunno. is there a java debugger for emacs?

12:56 _brian2_: Moominpapa: I also suggest downloading clojure box which is a windows prgram (and works in cygwin)

12:56 Blkt: dfa2: we

12:57 Moominpapa: Aaaaah

12:57 That I didn't know about. Thanks :)

12:57 _brian2_: good learning tool

12:58 Moominpapa: I'm mostly a .NET developer, but I'm feeling the need to learn something new and stop seeing things in terms of the tools I'm using.

12:59 chouser: beware -- learning clojure and then not being required to use something else instead can threaten one's mental health.

12:59 er

12:59 -not

12:59 man, what a way to ruin a joke. :-P

13:00 Moominpapa: lol (at the joke)

13:00 _brian2_: i was hoping that clojure would solve all my problems

13:03 Moominpapa: So far, I've merely been encountering them. Six hours to "Hello World" and counting (yeah, I can do it in a repl)

13:11 _brian2_: Moominpapa: its a steep climb, I wasn't a lisper, but now I'll never go back, for me just dispensing with loops and indexes was enough

13:14 Moominpapa: C#'s already got rid of those :) (kinda) It's multi-methods that interest me.

13:14 I'm looking forward to reconfiguring the way I look at things

13:15 tufflax: Can one return multiple values in Clojure, as with 'values' in Common Lisp?

13:15 hiredman: clojure uses the normal java method call stack, so no multiple returns

13:15 tufflax: ok

13:15 chouser: tufflax: no, but it's not uncommon to return a vector of multiple values and use destructuring in the caller

13:16 hiredman: you can emulate multiple returns with binding and set!

13:16 chouser: but that's not idiomatic or recommended. :-)

13:16 tufflax: ok, thanks guys

13:18 hiredman: chouser: the docs for binding suggest that it is

13:19 in fact it is the only mentioned use for binding, none of this resource management stuff :(

13:19 "Bindings created with binding cannot be seen by any other thread. Bindings created with binding can be assigned to, which provides a means for a nested context to communicate with code before it on the call stack."

13:20 before it, not after it

13:20 chouser: yeah, but how often have you seen that used?

13:21 I think it's mentioned because it's a non-obvious feature, not because it's recommended.

13:21 the only place I've seen that done extensively is in the clojure compiler itself.

13:21 it's a bit scary and slated for removal, I believe.

13:22 hiredman: once the only legitimate use of binding is removed we can remove binding

13:22 actually the only place I have used that extensively is in a compiler

13:23 chouser: (binding [*foo* 0] (do-a-thing 5 "please") (prn *foo*)) ; <- printing anything other than 0 is scary

13:23 hiredman: *shrug*

13:24 you don't call it *foo* you call it *result2*

13:24 cemerick: rhickey: record serialization doesn't work because of a namespace reference in there somewhere.

13:25 Moominpapa: I just figured out the classpath problem. The classpath was fine. The example I was using was junk. Should have been "compojure.core"

13:25 hiredman: (with-multiple-results (call 1) (println *result2*))

13:25 Moominpapa: Still don't work ofc... :)

13:25 cemerick: rhickey: if that can't be eliminated, then I can make namespaces sorta-kinda serializable (i.e. just have them look themselves up upon "deserialization").

13:26 tufflax: chouser btw, I incidentally I saw your blog post "My path to Clojur" today :P How is your project euler solving coming along?

13:26 chouser: tufflax: heh. haven't touched it in ages.

13:26 tufflax: hehe, I have done it with python so far, I was thinking i should try some with clojure soon

13:27 chouser: actually, that's not quite true. I've spent much of the last week trying to fix up one of my solutions for inclusion in the book. I don't think it's going to make the cut, though.

13:27 tufflax: Clojure is a bit harder to learn than python, python one can learn in like an afternoon

13:28 chouser: tufflax: I think it depends on what you're used to. But yes, if like me you have background in a "wide variety" of procedular syntaxy languages, clojure's a bit steep at first.

13:28 project euler helped keep it fun.

13:28 tufflax: But learning python, and seeing the difference between python and java was what made me get around to trying lisp

13:30 well, back to learning :=)

13:35 Moominpapa: Got it working! Thanks for the help :)

13:36 And now my wife wants me... :)

13:37 cemerick: rhickey: ok, the namespace serialization issue ended up being straightforward, never mind.

13:39 eslick: Is there a way to have namespace A use symbols from namespace B such that if namespace C uses A it also gets the public names from B?

13:40 chouser: eslick: not in a way that's recommended, I think.

13:41 of course C can use B directly

13:41 Raynes: chouser: What about D? ;)

13:42 chouser: or A can provide its own vars that have the same names and are bound to the same values as B's.

13:44 eslick: I regularly want to use utilities from multiple contrib namespaces and my own and am tired of cutting and pasting the same set of standard utility references to (ns (:use ...))

13:44 So either I have a namespace that consolidates all these references that I can use

13:44 Or I can write a macro and insert it after the (ns ) statement which uses the appropriate libs

13:45 Licenser: greetings my lispy freinds

13:45 eslick: This must be a common convenience issue, I was wondering if there was a canonical answer

13:45 (although heading off to grab lunch now...back soon)

13:49 SynrG: if B's public things are really A's public things, shouldn't they be made so explicitly, then? (def b b/b) or so

13:52 except def is probably not right :p

13:54 stuartsierra: Duplicating Vars in multiple namespaces leads to subtle bugs.

14:01 eslick: What I really want is to have a "group alias" that allows me to :use names from multiple namespaces with a single reference.

14:02 so (:use my.libs.core) also gets me the equivalent to (:use clojure.contrib.str-utils)

14:02 chouser: There are some replacement ns macros floating around that may have that kind of capability.

14:02 eslick: I used to have a 're-export' macro for CL that put third-party package symbols on the export list of a package

14:02 I'll check it out, thanks chouser

14:03 chouser: But I think your own function to 'refer' what you want would be easy to write and not a bad idea.

14:05 wouldn't even have to be a macro. just (defn refer-common-set (doseq [x '[clojure.contrib.seq compojure.core ...]] (refer x)))

14:05 hm. though that's still 'naked use' which isn't so great.

14:06 a function that requires and aliases a bunch for you might be ok.

14:07 eslick: A simple convention could be to :use 'my.utils.core which provides a simple function (use-standard-utils) which sucks in all the stuff I usually want to use

14:07 Then I just insert that after my ns statement and get the namespace I want

14:08 cemerick: it's very unfortunate that the signatures of set and sorted-set aren't the same.

14:08 chouser: hash-set and sorted-set are the same

14:08 hash-set and sorted-set have the same signature

14:09 set is like vec

14:09 cemerick: hrm

14:09 yeah, but the fact that the latter is backed by the former is an impl detail

14:09 oh, I see what you're saying

14:10 I guess there should be a set-by to go with set and vec, then, to make everything analogous.

14:10 (not that I'm actually suggesting that right now)

14:11 chouser: yeah, I see what you mean.

14:22 cemerick: chouser: how can I reliably ensure I'm getting a chunked seq?

14:23 mmarczyk: a really nice Clojure question on SO:

14:23 http://stackoverflow.com/questions/2760017/producer-consumer-with-qualifications/2760224#2760224

14:23 sexpbot: "Producer consumer with qualifications - Stack Overflow"

14:23 chouser: do you mean something other than 'chunked-seq?'?

14:23 mmarczyk: I posted an answer

14:24 but maybe some of you guys have better ideas (or comments on mine) :-)

14:25 Chousuke: mmarczyk: I think you should use java's BlockingQueue thingies instead of making your own

14:25 LauJensen: mmarczyk: you should use while instead of empty recurs

14:26 mmarczyk: LauJensen: right, thanks, that's a must! (going to fix it now)

14:26 Chousuke: I guess so, but I was curious to see how it would work out without interop (except for sleep)

14:27 Chousuke: I guess I might edit in an alternate version based on a blocking queue to make the answer more useful to the OP

14:29 AWizzArd: ~max people

14:29 clojurebot: max people is 283

14:30 LauJensen: I think its a fine a very readable example, so if that was what you were gunning for, I think you got it right :)

14:31 mmarczyk: good to hear that, thanks :-)

14:32 although I now notice I was supposed to have producers block if the queue gets too long, oh bother... going off to fix it

14:35 LauJensen: ,(doc add-watch)

14:35 clojurebot: "([reference key fn]); Experimental. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or ref. Note that

14:36 LauJensen: Why are watchers still experimental ? Are they going away ?

14:43 stuartsierra: I think they're experimental because not many people have used them, thus the API hasn't been thoroughly tested.

14:43 mmarczyk: ugh, fixed now, but producer is a bit uglier now

14:43 I've used them just now to monitor queue lengths :-)

14:43 just for debugging / general interest, though

14:44 LauJensen: stuartsierra: ah okay

14:47 cemerick: rhickey: FYI, excluded EnumerationSeq and IteratorSeq so far. I still need to do some trolling for potential transient targets and add more tests, but this is looking pretty decent so far: http://github.com/cemerick/clojure/commit/5d7224cd9f0

14:47 Licenser: I'm sing them for the swing stuff to update the gui when something chanes

14:58 rsh: mmarczyk: i'd be interested to see how you would write it with java blocking queue; also, what is the overhead associated with an empty recur as opposed to a while?

14:59 mmarczyk: rsh: there's no overhead (except some time spent macro expanding), as while is implemented in terms of (loop [] ... (recur)) :-)

14:59 rsh: as for the blocking queue version, I'm interested to see how I'd write it myself ;-)

14:59 rsh: so I suppose I'm going to do it in a moment

15:00 rsh: mostly I'd like to substantiate my claim that the code "would be easy to adapt" to a Java queue

15:01 not all like it, though, I actually got downvoted :-)

15:01 oh well

15:02 alexyk: I need to unroll a nested sequence, writing key pairs numbered: (doseq [[k1 v1] s] (doseq [[k2 _] v1] (put [k1 k2] i)) # I need to produce consequtive i's. Can this be done in doseq, or I'd have to use a loop?

15:11 rsh: mmarczyk: can you explain why you used (ensure queue) instead of just @queue ?

15:13 mmarczyk: rsh: to prevent write skew

15:13 rsh: if two producers found that (count @queue) is 3, they'd both place items on the queue

15:13 rsh: with ensure this won't happen

15:14 rsh: similarly with consumers; I wouldn't want two consumers to take the same element off the queue, then have the queue popped twice

15:15 ,(doc clojure.contrib.seq-utils/indexed)

15:15 clojurebot: "([s]); Returns a lazy sequence of [index, item] pairs, where items come from 's' and indexes count up from zero. (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])"

15:16 mmarczyk: alexyk: see above; the lib is called c.c.seq in HEAD

15:17 alexyk: I read, from a database, a sequence where each element has the form, [[k1 k2] v]. I need to create from them a nested map, {k1 {k2 [v ...]}} -- is there a faster way to do it than update-in?

15:17 mmarczyk: thanks! Did it with a nested reduce (fn [i [k v]] ...)) for now

15:18 in the nested map, v's are conj'ed into an array

15:32 mmarczyk: rsh: I added a java.util.concurrent.LinkedBlockingQueue-based version

15:32 rsh: it is indeed almost the same as the original :-)

15:33 alexyk: do you need the ordering of the vs to be preserved?

15:33 rsh: mmarczyk: cool i'll take a look

15:35 mmarczyk: how does ensure work under the covers? do the other transactions block until the transaction that got it first completes?

15:36 mmarczyk: ensure acquires a read lock on the Ref

15:37 so if some other transaction attempts to commit changes to an ensured Ref, it will fail and retry

15:38 if you never modify the ensured Ref in a transaction, that read lock will last you until the end of the transaction try

15:38 if you do, it will be released prior to acquiring the write lock when doing alter or sth

15:38 because read locks cannot be upgraded

15:39 so that's one scenario where another transaction could possibly slip in

15:39 get a lock after you released your read lock, but before you manage to acquire the write lock, I guess

15:39 if I understand the situation correctly...

15:40 but consistency is still guaranteed, because your trans will notice that something is amiss and retry

15:40 alexyk: mmarczyk: v's can be shuffled

15:40 mmarczyk: alexyk: in this case, you could do two things

15:40 alexyk: the first one you could do anyway and that's moving to a transient map

15:41 alexyk: the second is splitting the work in chunks, building a couple of maps in parallel, each based on a subset of the data

15:41 alexyk: then merging the maps at the end

15:41 alexyk: this might make sense if your dataset is large enough

15:42 alexyk: you'd want to perform the merging with this function:

15:42 ,(doc merge-with)

15:42 clojurebot: "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

15:42 mmarczyk: alexyk: the `f' you'd be passing to merge-with would have to take care of concatenating the v vectors

15:43 alexyk: this is where some shuffling could conceivably occur, depending on how you handle things

15:50 alexyk: is there an update-in! yet?

15:51 mmarczyk: nope :-(

15:52 alexyk: so if I run merge-with on a vector of a million triples, converting each to a small map, is it silly?

16:03 mmarczyk: um, that's a bit hard to tell without knowing how did you come by all those triples ;-)

16:04 if it's all data from your db and you'd really like to merge it, then perhaps do a test run and see if it's fast enough

16:04 oh, now I'm not sure if I understood your question correctly

16:04 merge-with accepts arguments which already are maps

16:06 rsh: mmarczyk: your linkedblockingqueue solution really cleared up some things for me, thanks for your help. The only other question I have is that you use poll to prevent waiting forever..what is the clojure idomatic way of killing a thread if necessary?

16:17 alexyk: if I reduce over triples, and find nested map is absent, do I get better performance creating it with (hash-map k v) vs. {k v} ? I.e., will the latter lead to changing the underlying map when it grows larger?

16:17 * alexyk remembers something about the literal small maps being different

16:17 Chousuke: measure it :)

16:18 though my guess would be that the difference is negligible

16:18 alexyk: Chousuke: I want the theory, not mere practice! :)

16:19 the underlying will be destroyed anyways as it's not persistent... so probably just at one step a different thing will succeed previous one, indeed

16:21 Chousuke: are you trying to write update-in!?

16:22 or was it you who asked about it?

16:22 mmarczyk: rsh: I'm not sure there is a general method of killing a Java thread, but in this case I now notice that I'm doing it all with futures and so could just hold on to them and kill them off with future-cancel at the end

16:23 Chousuke: there's the stop method of the Thread class, but it's deprecated

16:24 replaca: dnolen: ayt?

16:24 Chousuke: it's the only way to really kill a thread though.

16:24 dnolen: replaca: hola

16:25 replaca: dnolen: hey, I wanted to give you a heads up that pprint is changing (moving into core and losing it's gen-classing), so we'll want to change the macroexpand in swank too

16:26 mmarczyk: Chousuke: I myself have witnessed it not work, though :-(

16:26 replaca: dnolen: we'll keep it in contrib (deprecated) for another release, so it's not that much of a hurry, but it's on my mind today :-)

16:26 mmarczyk: (um, actually I meant to say "have myself")

16:27 dnolen: replaca: cool, does this pertain to specific project of mine that you want to see patched for this change? (sorry a bit slow today)

16:27 replaca: dnolen: didn't you add pprint to swank ages ago? Or is my memory getting fuzzy...

16:28 dnolen: replaca: I did the first pass (in 2008 or something), but jochu actually tweaked my code quite a bit.

16:29 technomancy: dnolen: that still leaves you as the person most qualified to patch it. =)

16:29 but I'll do it eventually if you don't.

16:29 dnolen: technomancy: haha :)

16:29 sure I can look into it.

16:30 replaca: are those changed pushed already?

16:30 changed -> changes

16:30 replaca: yeah, I had to expand a macro this weekend (when I didn't have contrib loaded) and it was a disaster.

16:30 I was very sad :-)

16:30 dnolen: replaca: ahh, so this was already pushed?

16:30 replaca: dnolen: I just added the patch this morning, but I think it will go through very quickly

16:31 dnolen: nah, I was working on my fork

16:31 dnolen: replaca: ok just to be clear, what do I need to do to reproduce?

16:32 leifw: is there a transpose function that works on lazy-seqs?

16:33 namely, (transpose '((1 2 3) (4 5 6))) #=> ((1 4) (2 5) (3 6))

16:33 wait that's just zip

16:33 haha

16:34 replaca: dnolen: once the patch gets pushed, load clojure w/o contrib on your path. Then expand a macro. Ewww! (though no different from what would happen in 1.1)

16:35 dnolen: replaca: ok, will do.

16:35 replaca: dnolen: But in 1.2, pprint will be clojure.pprint (and *also* clojure.contrib.pprint). But in the next release, clojure.contrib.pprint will go away

16:36 dnolen: so, like I say, no real hurry

16:36 technomancy: replaca: congrats on the promotion

16:36 you haven't had many changes to it recently, have you?

16:36 replaca: technomancy: thanks much

16:36 technomancy: because the downside of not being able to fix bugs on your own can really be a bummer. =\

16:37 replaca: technomancy: no, not too much. I did make sure to close out the one open ticket before promoting it :-)

16:37 clojurebot: technomancy is to blame for all failures

16:37 dnolen: replaca: I suppose we want the fix to work with 1.1 and 1.2 ? what's the approach that was decided upon for supporting multiple version of Clojure?

16:37 technomancy: clojurebot: shut up, you.

16:37 Borkdude: ,(apply map list '((1 2 3) (4 5 6)))

16:37 clojurebot: ((1 4) (2 5) (3 6))

16:37 Pardon?

16:37 replaca: dnolen: I don't know - I would just try both, since we're trying things there anyway

16:38 when we decide that 1.1 is acient history we can stop trying and charge blindly ahead

16:38 knowing that we have what we need

16:38 *ancient

16:39 * dnolen remembers seeing some talk about :as-of on channel recently ...

16:39 leifw: Borkdude: doesn't work on lazy seqs I don't think

16:39 technomancy: I would like to support 1.1 in swank for a while, but if macroexpand turns ugly a few releases down the line I think that's acceptible.

16:39 replaca: technomancy: There are still some big changes under the hood to come for pprint/format to support higher performance. But Stu promises that the delays won't be too bad :-)

16:39 leifw: Borkdude: yeah definitely doesn't

16:39 technomancy: replaca: yeah, it has helped a lot bringing Stu on board.

16:42 replaca: technomancy: the last few weeks have been a flurry of activity! I feel like we're getting some fit and finish as well as big conceptual features. More smart people with good taste = an even better language :-)

16:43 Borkdude: leifw, I didn't follow what you wanted, just saw the zip/transpose thing

16:43 technomancy: replaca: inc

16:44 (anyone else find themselves usinc inc instead of +1 in circumstances where they won't be understood?)

16:44 replaca: technomancy: admit it: you're a member of a cult :)

16:44 Borkdude: It's where others use InterlockedIncrement, inc sounds better

16:45 * technomancy quaffs a tall glass of PersistentKoolAid

16:45 replaca: technomancy: Q: is me having clojure as a dep in autodoc causing the problem that Joshua reported on the list?

16:45 technomancy: replaca: pretty sure that's the culprit, yeah

16:46 replaca: technomancy: and Q2: what's the best practice for pushing the fix to clojars, should I just push over the existing version 0.7.0 or make a new version?

16:46 technomancy: replaca: I'd do 0.7.1

16:46 might be able to get away with overwriting it since the code didn't change, but that's very iffy.

16:47 replaca: technomancy: k, thx!

16:47 stuarthalloway: replaca: I am seeing an issue with the new clojure group-by in the contrib pprint. Ok if I fix it?

16:49 replaca: stuarthalloway: sure. where's the issue?

16:49 stuarthalloway: oh, in the examples?

16:49 stuarthalloway: what I am seeing (locally) is the issue caused by group-by being promoted to clojure

16:49 but I don't know why it wouldn't have broken the build

16:50 replaca: stuarthalloway: what file? We don't AOT everything in contrib & we don't load the examples during testing.

16:50 stuarthalloway: yeah, this is making no sense atm

16:52 replaca: nevermind. ancient build lurking on my machine

16:52 replaca: stuarthalloway: ahh, ok

16:59 leifw: Borkdude: thanks for the help though

16:59 I think I got it

17:00 stuarthalloway: replaca: the pprint move looks pretty good. anything in particular I should check before I mark it screened for Rich?

17:00 leifw: I'm just in a state where what I expect and what is true about lazy sequences are quite different, and I don't have a great handle on what functions are allowed to work with them and what aren't

17:00 but it's all good now, I believe, my job continues to run

17:04 whoo yeah

17:26 tcepsa: Is there a recommended way of using log4j in Clojure namespaces that you're going to compile into classes?

17:28 I'm trying to set up a logger but don't know how that would look; usually I create them a private static variables, but I can't figure out how to get the class name to instantiate the logger and I don't know how to make it static or private (though I can probably find the last two; it's the getting-the-class-name-to-Logger/getLogger that I'm having trouble with).

17:33 eslick: Does count eval lazy sequences?

17:35 dakrone: eslick: looks like it does to me

17:35 (count (map println [1 2 3]))

17:36 ,(count (map println [1 2 3]))

17:36 clojurebot: 3

17:36 1 2 3

17:36 eslick: So it's O(1) assuming the sequence has been fully evaluated

17:41 PS - nstools has an answer to my earlier question about 'cloning' common namespace use patterns

17:41 replaca: stuarthalloway: nope, I think it's should be pretty straightforward for something so big

17:43 eslick: Any recommendations on doing production development on 1.1 or starting with the upcoming 1.2 now?

17:43 Community seems in transition; unclear which way to jump for a near-term project

17:51 replaca: eslick: unless you need some 1.2 features, I'd stick with 1.1. 1.2 shouldn't be too hard a conversion, but you might want to let the forward guard find library problems and such. Plus 1.2 is still changing every day right now (though that should end soon).

17:52 eslick: Good advice. That's where my head was, but I occasionally run into things depending on 1.2 and will avoid them for now.

17:52 thanks!

17:52 MadWombat: Hello

17:52 eslick: Last silly question of the day...

17:52 replaca: eslick: np. Good luck!

17:52 eslick: What is the elegant way of (apply struct-map my-struct <map>)

17:53 with a map of the keys and vals that I'd prefer were in an actual sequence

17:53 This works for (apply struct-map my-struct [:a 1 :b2])

17:53 But apparently not for (flatten (seq kvmap))

17:54 MadWombat: hi!

18:02 MadWombat: anyone configured auto-complete-mode to work intelligently with clojure?

18:03 bmason: not sure if this is what you're talking about, but auto complete seems to work fine in my emacs REPL, just not in the code files

18:04 MadWombat: bmason: yes, swank provides autocomplete to slime sessions, but I want autocomplete to work in the code

18:04 bmason: like with the fancy IDEs

18:04 bmason: MadWombat: yeah understood... I don't know if the underlying mechanism is compatible

18:05 MadWombat: I'm still new to emacs

18:05 MadWombat: Yeah, me too

18:06 _ato: ? you can use swank's auto-complete while editing source code

18:07 just use C-c <tab>

18:07 MadWombat: _ato: heh, gotta check

18:08 _ato: make sure you eval/compile the relevant parts of the file first so it knows what to complete on (C-c C-k should do the whole file)

18:08 MadWombat: _ato: cool, now I need to figure out how to plug this into auto-complete-mode

18:08 _ato: yes, of course

18:09 Borkdude: C-c <tab>: good to know!

18:11 dfa2: MadWombat: in the case you care I've a macro that indents or complete only with TAB

18:11 Borkdude: dfa2, I care

18:11 _ato: Borkdude: (re: bookmark syncing on Conkeror) I don't use bookmarks, but I think it uses the same storage mechanism as firefox so some of the firefox bookmark syncing extensions might work with some tinkering

18:12 Drakeson: (deftype foo [a]) (foo. 10) -> ok (new (resolve 'foo) 10) -> broken

18:12 am I missing something?

18:13 Borkdude: _ato, ok tnx

18:13 dfa2: Borkdude: http://gist.github.com/388648

18:15 Borkdude: dfa2: gonna try that now

18:15 * technomancy cheers for Conkeror

18:15 technomancy: but yeah... I wish Chromium would support extensions like that. =(

18:17 Borkdude: dfa2: am I supposed to reload slime to activate it or smth?

18:17 dfa2: Borkdude: no, just reload your .emacs with M-x load-file

18:17 Borkdude: dfa2: evaluating in *scratch* suffices as well?

18:18 dfa2: yep :)

18:18 Borkdude: dfa2, ah I had to reopen the clj file, now it works

18:18 great! :)

18:19 dfa2: ^_^

18:19 Borkdude: dfa2: what's with the minibuffer in that code then?

18:23 dfa2: Borkdude: vestigial code :)

18:26 Borkdude: dfa2: right, I get it. This is going into my init.el now ;-)

18:28 MadWombat: seems like (add-hook 'clojure-mode-hook (setq ac-sources '(candidates . (slime-complete-symbol)))) works

18:46 Borkdude: Hmm, how do I get a pvt chat window in erc with someone?

18:49 /msg dfa2 ;; Thanks to dfa2 in #clojure


18:54 technomancy: Borkdude: put the point on their nick and hit RET, then Msg

18:57 Borkdude: technomancy: tnx, maybe you only get a buffer for that person when a person talks to you, so it won't mangle up with your existing buffer?

18:58 technomancy: yup. not terribly fond of that choice, but that's how it works by default.

19:07 rsh: if you send an agent several functions to run..do they run in the order in which they were sent?

19:08 _ato: rsh: yes

19:09 (of course if they're sent from seperate threads the order might be non-deterministic, but functions sent sequentially from one thread will be executed in the order they were sent)

19:14 Borkdude: technomancy: I was after /query

19:23 MadWombat: I have a bunch of web site scrapers that I need to run in parralell and save the data in a database, at this point this is what I came up with http://pastie.org/944419 but it doesn't seem to parallelize and seems a bit awkward, what would be a better way?

19:25 _ato: futures might be more appropriate if you want to run them all in parallel

19:25 pmap will only run up to the number of cores your machine has in parallel

19:25 since it'll be blocking on IO you probably want more than that

19:26 ,(doc future)

19:26 clojurebot: "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."

19:27 MadWombat: how do you wait for futures to actually execute?

19:27 or will deref block until the particular future is ready?

19:29 ah! got it

19:40 Borkdude: When you have two futures in a let statement, can you see which finishes first?

19:53 _ato: I suppose you can loop checking (.isDone some-future), or have them do something side-effecty (like print "I'm done!") when they finish

19:55 Borkdude: http://gist.github.com/388755

19:55 _ato: I tried printing but that didn't work

19:56 _ato: oh, if you're doing it in slime, printing from another thread usually goes to the *inferior-lisp* buffer, rather than the repl or minibuffer

19:56 Borkdude: ah, that explains it

20:09 zakwilson_: Does (vals a-map) make something like a full copy?

20:11 MadWombat: _ato: this is what I came up with, it seems to work, but somehow time macro doesn;t print anything http://pastie.org/944467

20:14 zakwilson_: I am not sure, but I don't think so. If I understand the concepts correctly the values in clojure are immutable, so there is no point in making a copy, clojure can just point you at the same values

20:14 arohner: zakwilson_: no

20:15 zakwilson_: vals creates a lazy seq that walks through your map

20:16 zakwilson_: Does it copy data at all, or just reference it?

20:16 arohner: no copies at all. Since clojure datastructures are immutable, the map you have in hand will *never* change

20:16 so it's never copied

20:17 rsh: i want to change some of the font colors (particularly, for string) in clojure-mode for emacs, but don't see anywhere in clojure-mode.el that defines colors. Can someone point me in the right direction?

20:17 zakwilson_: I know it never changes. I just wasn't sure if the resulting seq would be structured so as to re-use the values.

20:18 _ato: MadWombat: why not just do (doseq [t threads] (deref t)) instead of the count loop? (or are you intending to print a status of the number that have finished so far?)

20:18 where are you putting the time macro? inside each future?

20:20 MadWombat: _ato: (future (store-site (time ((val scraper)))))

20:21 _ato: I presume that deref will return nil immediately if the future is not done yet, or does it block?

20:21 _ato: ah missed that, deref blocks

20:21 MadWombat: Ah!

20:22 _ato: hmm yeah, when I run 'time in a future the output goes to *inferior-lisp*

20:23 MadWombat: heh

20:23 that is fine, this is for debugging only

20:24 _ato: looks like using (future-call (bound-fn [] (time ...))) will print it to the repl though

20:32 MadWombat: _ato: the latest version looks like this http://pastie.org/944490 and for some reason it runs sequentially (at least according to the log messages I get)

20:35 _ato: MadWombat: put a doall around your (for ...)

20:35 the 'for is lazy, so it's actually creating the futures until you deref

20:35 doall will force it

20:36 MadWombat: _ato: Ah! Lazy seqs!

20:36 technomancy: clojurebot: science is http://sunpig.com/martin/images/2008/10/iwilldosciencetoit.jpg

20:36 clojurebot: Alles klar

20:36 * MadWombat is enlightened

20:37 pjstadig: clojurebot: meap

20:37 clojurebot: Manning missed the opportunity to call it Manning Early Access Trial

20:47 defn: Any ideas for pretty printing anonymous functions so they come out like #() instead of (fn* [p1__6334] (not= \: (first p1__6334)

20:48 rsh: how do I tell leiningen to put postgresql driver jar on the classpath?

20:48 chouser: defn: whew, sounds tricky

20:48 defn: chouser: :)

20:48 technomancy: defn: you'd need to either write a decompiler or store the original pre-compiled source in metadata

20:48 the latter wouldn't be bad if it were easy to turn off in production

20:48 chouser: well, I dunno if it's *that* tricky

20:49 defn: well the first option certainly wont be happening

20:49 technomancy: though it'd be a bit tricky to support with comp/partial/etc

20:49 chouser: he seems to have the source as read

20:49 defn: yeah im doing (pprint (read-string "(foo #(bar %) baz)")) right now

20:50 so the metadata thing is possible

20:50 technomancy: defn: I bet it's doable, but you'd have to deep-dive into the compiler. sounds like lots of fun if you've got some time to sink. =)

20:50 _ato: rsh: add [postgresql "8.4-701.jdbc4"] to your :dependencies in project.clj? (not sure if that's the version you want, search jarvana.com)

20:51 defn: technomancy: frankly i just have no clue where to even start, got some time to mentor me? ;)

20:51 aka to sink? :)

20:52 technomancy: defn: I will bring it up for discussion at this week's seajure meeting

20:52 it'd be a fun thing to try to track down

20:52 defn: technomancy: oh man that'd be awesome

20:52 technomancy: will report findings, if any. =)

20:53 defn: fantastic! thanks!

20:53 chouser: does pprint not use a multimethod?

20:54 defn: !source pprint

20:54 chouser: ah, perhaps I found it.

20:54 technomancy: defn: actually it's probably more of a reader thing than a compiler thing, which is good because at least two people in here know the reader pretty well.

20:54 defn: hiredman and chouser?

20:54 technomancy: was thinking of Chousuke

20:54 defn: ah, yes

20:54 technomancy: but he probably does too

20:55 defn: of course he does :)

20:55 </jealousy>

20:55 replaca: chouser: yes, pprint uses a multimethod

20:55 chouser: clojure.contrib.pprint/*print-pprint-dispatch*

20:55 replaca: chouser: in fact you can put any function you want in that var

20:56 but both code-dispatch and and simple-dispatch are multimethods

20:56 chouser: you'd just want to implement a slightly different fn for PersistentList

20:57 replaca: what's the question? I just dropped in

20:57 oh, defn

20:57 just use the code-dispatch

20:57 defn: pprinting #() as #() instead of (fn* [p_8142] ...)

20:57 replaca: that's all, really?

20:57 replaca: it does that for you:

20:57 chouser: ha!

20:58 defn: bahaha

20:58 replaca: (with-pprint-dispatch *code-dispatch* (pprint ...))

20:58 it'll make your code all purdy

20:58 defn: purdy codez

20:58 replaca: note the version that's going into core loses the ears

20:58 since it's not really meant to be rebindable

20:59 defn: for 1.2 you mean?

20:59 no more earmuffs?

21:00 chouser: I don't understand how to use code-dispatch

21:00 replaca: yeah, it does all sorts of great things... nice indentation of let, if, etc.; quote turned into ' etc

21:00 defn: id like to know more if anyone wants to explain

21:00 replaca: chouser: just like my example...

21:01 chouser: ah, I see it now. thanks.

21:01 very nice

21:01 replaca: defn: earmuffs are those *s on the ends of *code-dispatch*. convention says you use them on vars that are meant to be rebound

21:01 livingston: the dispatch function on a mutimethod get's passed all of the function calls arguments right? but i just wanted to dispatch on the first I would give my dispatch function the signature [first & _] ?

21:01 defn: replaca: ah-ha

21:02 replaca: pprint has a ton of vars like that, but simple-dispatch and code-dispatch really aren't that way

21:03 if you want to customize, just create a new defmulti and default (if appropriate) back to the dispatch of your choice

21:03 if you look in the contrib examples there are examples of using custom dispatch to create xml or json

21:04 livingston: in this case it gets passed the object your pprinting

21:05 it's called at each level - the idea is that you call pprint function from inside

21:05 * technomancy was actually wondering about clean representations for compiled fns rather than quoted source forms

21:05 defn: replaca: which contrib examples

21:05 livingston: replaca: I'm only kinda following your dispatch question, .. I happen to have run into it myself too for a different question ;)

21:05 replaca: look in the contrib source in something like src/main/examples/pprint

21:06 defn: ah, great -- thanks

21:06 replaca: in any case, gotta run, bbl

21:11 livingston: the dispatch function in a defmulti gets called with every argument passed to the main function, right?

21:11 defn: beautiful.

21:11 so happy i didnt need to decompile

21:16 bmason: so... Clojure being my first FP language, I'm really unfamiliar with the design approaches that are commonly taken

21:16 is there some equivalent to design patterns for FP?

21:20 * MadWombat bored with web scrapers

21:20 livingston: bmason: there's a whole 'nother set of idioms you will want to get your head around, like map and reduce ... new core functions to the language that you probably won't be used to thinking with

21:21 * MadWombat is going to write a markov chain generator

21:22 livingston: starting with an intro book is probably the way to go (either for Common Lisp, Scheme or Clojure) and thinking about the exercises will help

21:22 bmason: I read through Stuart Halloway's book

21:23 I guess I'm looking for a more guided approach to designing and architecting a FP solution

21:24 the direction I'm planning now is to analyze source of some existing projects out there

21:24 but that's not quite the same as having an explanation of why a certain design was chosen

21:25 livingston: bmason: that would be worthwhile, although I would encourage you to find a project and not a library (if you can).

21:25 MadWombat: well, personaly I started with the SICP http://mitpress.mit.edu/sicp/full-text/book/book.html

21:25 sexpbot: "Structure and Interpretation of Computer Programs"

21:26 rsh: what is the best way to go about writing database code in clojure? clojure.contrib.sql or clojureql? neither?

21:26 sql database that is

21:26 MadWombat: it is in scheme, but it a good start into FP

21:26 livingston: the problem with SICP and On Lisp is they don't go about building large projects, but if you do what they guide you to do and the small level and build up, you'll do ok-ish

21:27 bmason: hmm

21:27 k

21:27 MadWombat: Spels in Clojure is supposed to be fairly decent

21:27 http://www.lisperati.com/clojure-spels/casting.html

21:27 bmason: I am planning to read On Lisp as well

21:27 sexpbot: "Casting SPELs with Clojure - Home -"

21:28 MadWombat: haven't read it yet

21:28 bmason: very nice

21:28 I'll definitely dig into that

21:28 remleduff: rhickey: Sorry about the process mixup, submitting a patch to assembla before mailed my CA. I'll drop it in the mail tomorrow morning. Can I just say "I release this into the Public Domain" and make everything ok for now?

21:29 * _ato thinks you should never have building a large project as your goal. ;-) It may unfortunately get that way anyway but you should try as hard as you can to keep things from getting big

21:29 livingston: _ato: a fair enough goal

21:30 bmason: lol, sounds like sage wisdom

21:30 livingston: bmason: to the original question, I think if you just build up, step into working on something, start small, write one function to a function and refactor when possible, you'll get some decent code out of it.

21:30 rhudson: "Every big system that works well started out as a small system that worked well"

21:32 livingston: the advantage of starting in clojure is it will force a little more of the functional style on you, than you would get in a more mutable language like common lisp, which relies on discipline in stead of design to get good functional code

21:32 bmason: ah

21:32 I wasn't aware that CL was different in regards to mutability

21:33 but yeah, I think it's appropriate for a language which requires you to *think* differently have a different syntax

21:33 _ato: I suppose the more general stuff applies when it comes to architecture. Build things in layers (so higher layers depend on lower layers) and avoid circular dependencies like the plague.

21:34 bmason: ok

21:34 but take something like Stuart Halloway's snake game

21:34 Associat0r: "CLI on the Web" http://tirania.org/blog/archive/2010/May-03.html

21:34 sexpbot: "CLI on the Web - Miguel de Icaza"

21:34 bmason: in that, he has a function that returns a map containing all the doohickeys you need to run the game and find out what its state is

21:35 which I thought was an interesting idea, and in a way it strikes me as a design pattern

21:35 a common way of doing things which applies to certain scenarios

21:36 livingston: (actually it *is* the state - as I remember)

21:36 bmason: true :)

21:37 I figure there's probably volumes out there that describe that sort of thing in terms of where you would use it and why

21:38 livingston: the point to the example is that you're not side-effecting things (like you would be encouraged to do in a procedural language, for example) - you have a function you put in inputs you get out outputs - nothing else should change (if it's a pure function)

21:40 the input snake isn't modified, you just produce a new snake. and if you know the old snake can't change (like you are guaranteed in clojure) you are free to share any of it's structure in the new snake, making creating a "whole new one" really cheap

21:41 bmason: right, and I get that

21:42 I think he presented a good case for immutability

21:42 my question pertains more to resources for learning though

21:42 livingston: that's not really a "pattern" per say, it's just "what you do" in functional languages

21:42 bmason: :)

21:44 livingston: bmason: oh, well, On Lisp isn't bad then, but it'll have you thinking in CL not Clojure

21:44 bmason: know of any web projects that are examples of good coding?

21:47 livingston: bmason: not off the top of my head, in clojure at least (i liked the ones I built but those are published/available) I'm sure there are plenty of projects with open tasks looking for some help, you could try to contribute to though

21:48 are published -> are not published/

21:48 bmason: ok... thanks for the ideas :)

21:48 I may publish some of my stuff on github too and try to get some feedback

21:51 remleduff: bmason: I'm liking the cow blog: http://github.com/briancarper/cow-blog/tree/master/blog/

21:52 I'm coming to the sad realization that my web project is not currently an example of good coding :\

21:52 bmason: lol

21:53 yeah, I'm sorta tackling a RESTful API at the moment

21:53 so learning about doc types and HTTP headers at the same time as I'm picking up steam with Clojure

21:53 remleduff: I've been doing the same thing, never written a web app in my life

21:54 So decided to learn: clojure, emacs, compojure, enlive and fleetdb all at the same time

21:54 bmason: well heck, this is the first time it's seemed worth doing :-P

21:54 livingston: when I say (ns ... (use a.b.c.d-e-f)) it's saying can't find a/b/c/d_e_f.clj on the class path? I can't have hypens? or is there something else I missed?

21:54 remleduff: replace - with _ in your filenams

21:54 bmason: web technology is really starting to mature

21:55 livingston: remleduff: really? that sucks - are hypens somehow invalid in java/jvm filenames?

21:55 bmason: livingston: is your file on the classpath?

21:55 livingston: bmason: yes

21:56 remleduff: Yeah, you can't have "-" in packages. So both "-" and "_" are mangled to "_" by clojure to allow it in namespaces

21:58 livingston: ugh - boo, but ok.. is *cringe* CamelCase preferred for this kind of thing?

21:58 solussd: and it's only a couple steps away from a monad. :)

21:58 remleduff: I think lots of people just name their file "some_package" and then (require 'some-package)

21:59 I tend to avoid it and just add an extra directory to my package path

21:59 So it would be "some/package.clj" and (require 'some.package)

21:59 livingston: remleduff: it's already 6 deep .. the underscore will do

21:59 Associat0r: snake_case

22:03 cemerick: livingston: top-level namespaces are strongly discouraged.

22:04 * defn is guilty

22:05 livingston: cemerick: I don't have any top level ns'es? like I said, I'm 6 deep already, you lose 3 just putting your institution on the front of the dang thing

22:05 remleduff: At least you aren't in ".co.uk" ;)

22:06 cemerick: livingston: yeah, that was just an FYI :-)

22:06 there's no requirement to doing org.name.foo.bar.bang -- could easily be projectname.module.ns-name, etc.

22:07 livingston: so let's say I have a lot of functions I want to dispatch on the same first arg, this would be an ok/correct dispatch function to give them all? (defn server-type-dispatch [server & _] (type server)) ?

22:08 cemerick: yeah, I could probably get away with that too, but I'm in an academic lab that's integrating with a lot of java, so edu.... it is

22:09 cemerick: livingston: sure, or you can do #(type (first %&)) if you want to be concise about it. :-)

22:10 livingston: I'll favor the readable one, for clarity, unless there is an efficiency argument to be made? this will get called *a lot*

22:11 cemerick: it's *slightly* more efficient (saving a var dereference), but the point is that the anon fn is semantically general (type of first argument), rather than declaring that it's a server type dispatch fn.

22:11 *shrug*

22:15 livingston: ok, well I'll go with the obvious one until the profiler convinces me to do otherwise then

22:16 remleduff: cemerick: What is the apersand there?

22:16 cemerick: remleduff: rest arguments

22:17 ,(#(do %&) 1 2 3 4)

22:17 clojurebot: (1 2 3 4)

22:17 remleduff: interesting, learn something new every day :)

22:17 cemerick: ,(#(do [%1 %2 %&]) 1 2 3 4)

22:17 clojurebot: [1 2 (3 4)]

22:17 livingston: I have to deal with the fact that I'm applying that dispatch function to many different defmulti's with different arity -and the dispatch function gets called with all the arguments of the main function so...

22:18 cemerick: fn literals have almost all of the argument options that normal fns do.

22:18 livingston: cemerick: I would expect them to have them all? which ones are they missing?

22:19 cemerick: livingston: this is well into style and idiom here, but IMO, the best thing to do would be to def the fn literal in one place, but not specify that it's applicable only to servers, etc.

22:19 livingston: It doesn't have rest kw args, which are a recent addition.

22:19 remleduff: If I don't have a defstruct to dispatch by type on, is it ok to make a defmulti hierarchy that just dispatches assuming the first arg is a keyword I provide?

22:19 livingston: cemerick: keywords like in common lisp? (that would be nice)

22:20 cemerick: remleduff: yes, though if you're using 1.2, it sounds like you'd be happier with records and protocols.

22:20 livingston: essentially, yes.

22:21 livingston: cemerick: well, the first arg is actually a map SO really it's calling (defn server-type-dispatch [server & _] (:server (type server)))

22:21 cemerick: ,((fn [& {:keys [a b]}] [a b]) :a 5 :b 6)

22:21 clojurebot: [nil nil]

22:21 livingston: although I guess I could do that with destructuring on the first arg too

22:21 cemerick: bleh

22:21 ,*clojure-version*

22:21 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

22:21 livingston: yeah clojurebot is 1.1

22:21 cemerick: right, clojurebot doesn't have the newest stuff :-P

22:22 livingston: that's really nice though, something I was missing from CL - all these {} were really crudding things up

22:23 cemerick: A little sugar is good. :-)

22:24 remleduff: cemerick: What I was trying to ask was, is http://gist.github.com/388872 nonsense?

22:24 livingston: it's a little ugly on the definition syntax, but getting it right in the calling syntax is more important

22:25 anonymouse89: hi all, quick question: what does "for[[a b] c]" mean?

22:25 are a and b both taking values of c?

22:26 cemerick: remleduff: Seems fine to me.

22:26 remleduff: anonymouse89: It's using destructuring to take each element from the collection named c and split it into a and b which are available as vars inside the body of the for comprehension

22:26 cemerick: ,(for [[a b] [[1 2] [3 4]] (+ a b))

22:26 clojurebot: Unmatched delimiter: )

22:26 livingston: remleduff: does that even run?

22:27 cemerick: ,(for [[a b] [[1 2] [3 4]]] (+ a b))

22:27 clojurebot: (3 7)

22:27 remleduff: livingston: I'm not sure, was typing it directly into gist

22:27 livingston: lol

22:28 first I don't think you give the argument signature to defmulti, do you? second it'll end up calling (#(identity %) key val) to dispatch which will barf because identity wants a single argument

22:29 but... on it's face, I don't see much wrong with the basic idea that I think you are going for

22:29 anonymouse89: remleduff: thanks

22:31 livingston: remleduff: the thing is if it's a fixed set of stuff and you don't want/need it to be extendable by external code, then a code would probably be preferred (and possibly be more transparent)

22:32 code -> cond

22:32 remleduff: livingston: You're right, it didn't work. what I have now does, but seems a little iffy

22:33 I guess a cond would work well too

22:34 livingston: it'd be faster and more transparent as to what it is doing, but won't be externally extendable .. it depends on what you need....

22:34 remleduff: My webapp is growing (str "/" user) or (str "/media/" item) all over the place and I've been trying to decide what the best replacement would be

22:35 livingston: you could also just have a map that associates keys with functions to apply to the value (that's basically what the defmulti is buying you.

22:36 i'm ok with what you have, more or less, something about it seems ugly but I have no suggestion on how to better it if you need it to be defined distributed all over the place instead of a cond

22:37 rhudson: A downside of cond is that it's linear search.

22:38 (not an issue for a few keys)

22:40 livingston: I don't know what the overhead is in clojure but with the Franz Allegro Common Lisp compiler you would have to exceed about 60 keys before a PList was slower than a hash-table

22:40 the hash implementations are significantly different though - has someone run that experiment here? we should

22:41 regardless it's not really worth worrying about until the profiler get's upset at you

22:42 jhawk28: does anyone have any experience with writing an interpreter with Clojure? or should I look into using Antlr?

22:43 cemerick: livingston: array-maps cut over to hash-maps @ 16.

22:43 hiredman: are you kidding? writing an interpreter in a lisp vs java stuff?

22:43 multimethods are great for interpreters

22:43 slyphon: hiredman: yeah, but java's got...

22:43 ...stuff

22:44 hiredman: pfft

22:44 jhawk28: it needs to be able to execute (like the string reader) from Java code, but it is an s expression syntax

22:44 slyphon: :)

22:44 hiredman: yeah, multimethods all the way

22:44 cemerick: hiredman: BNF is really nice when it fits

22:45 livingston: right, but the jumps in hashes can do funny things to CPU lookahead compared to some more straightforward things - so you gotta measure it at the task at hand (presumably RIch did and found the break at 16)

22:45 hiredman: you can't see me rolling my eyes

22:45 jhawk28: the grammar is predefined

22:45 its LL too

22:45 * slyphon laughs

22:46 cemerick: something implemented in a common grammar is so very, very often superior to something that's hand-rolled.

22:46 livingston: I just call read

22:46 cemerick: There's good reasons to hand-roll things, but it shouldn't be the default choice.

22:47 slyphon: that's one thing that impressed me w/ scala, is the built-in BNF parsing stuff

22:47 there's something neat about being able to do stuff like that

22:47 cemerick: slyphon: you shouldn't be. Stuff like that shouldn't be in a general-purpose language.

22:47 * slyphon shrugs

22:47 cemerick: That's what libraries are for, quite literally.

22:48 slyphon: i mean, i think it was factored out into a standard library, like the embedded-xml functionality

22:48 it's been a while since i've looked at it, though

22:49 cemerick: I ended up having to use the embedded XML stuff quite a bit. Nightmare, pure nightmare.

22:49 slyphon: yeah?

22:49 * slyphon never had to do anything serious with it

22:49 cemerick: <xml><blah><foo>.........</foo></blah></xml>.callSomeXMLDOMMethod()

22:49 :-0

22:50 slyphon: hrm

22:50 yeah, i could see how that could get hairy

22:50 but still, it looks damn cool!

22:50 cemerick: it gets crazier, as you can interpolate values into the XML

22:50 * slyphon coughs

22:50 cemerick: yeah, it's very alluring, if you haven't gotten tangled in stuff like it before.

22:50 slyphon: :)

22:51 livingston: anything with a closing tag (that's required) is already inferior to an s-expression

22:52 slyphon: )

22:52 livingston: cemerick: I don't know that library, but jQuery is pretty damn cool for js stuff, and sounds like it has similar applications

22:53 slyphon: i heard a statistic the other day, that jQuery has 80% penetration

22:53 cemerick: livingston: was talking abou tthe inline XML support in scala?

22:53 I was*

22:54 livingston: I haven't looked at scala too much. it's primary selling point being "it's not java" wasn't quite good enough for me.

22:54 jhawk28: thanks for the tips

22:54 slyphon: well, "It's functional not java"

22:54 jhawk28: Ill look into the multimethods

22:54 slyphon: "..and it gives the guys at Twitter a stiffie"

22:54 remleduff: What does penetration mean for something downloadable by 100% of people with javascript?

22:55 slyphon: remleduff: it means 80% of the sites these guys were surveying were using it in one form or another

22:55 cemerick: that's probably a lowball estimate

22:55 * slyphon nods

22:57 slyphon: any language you can't use paredit to hack on is at a distinct disadvantage

22:57 livingston: .. headed out, dinner etc. -- thanks everyone

22:59 remleduff: I'm coming to emacs from a vim addiction, and still not really liking emacs as an editor, but paredit is amazing

22:59 mmarczyk: remleduff: I know what you mean, that's what got me hooked :-)

22:59 slyphon: yeah, i use vim for pretty much anything that's not s-exp based

22:59 mmarczyk: ...and now I'm using ERC to chat with you guys :-P

22:59 slyphon: hahaha

23:00 it's a slippery slope;2~

23:00 mmarczyk: :-)

23:00 slyphon: !

23:00 mmarczyk: well I always was curious about the dark side

23:00 slyphon: :D

23:00 mmarczyk: so it wasn't a painful switch, because I already knew my way around :-)

23:01 I use both Vim and Emacs now, makes for fun little lapses of concentration

23:01 slyphon: oy

23:01 and tangled fingers

23:01 mmarczyk: where I'm quitting Vim with C-x C-c :-P

23:01 slyphon: C-g!

23:01 or manically hitting ESC in emacs

23:01 mmarczyk: C-g is exactly what I press when I realise it doesn't make sense to press C-x C-c in Vim :-)

23:02 * slyphon did that not 15 minutes ago

23:02 mmarczyk: and before I actually regain my senses ;-)

23:03 remleduff: I still can't believe how many commands I use *frequently* take 2 or even three control characters

23:03 slyphon: yeah

23:03 vim-mode in emacs saves me a lot of heartache

23:04 remleduff: see, you're not supposed to use those keystrokes, you're supposed to reprogram the editor over the course of 10-15 years until it's an extension of your now corrupted mind

23:04 mmarczyk: :-D

23:04 remleduff: hehe

23:04 slyphon: :)

23:04 mmarczyk: that's the Emacs mindset summarised for you right there

23:05 slyphon: i had to stop with emacs a few years back, because i was having *way* more fun hacking on my editor than actually "doing work"

23:06 remleduff: I'm close to quitting emacs again now, every since I've changed computers I get a 3 second pause every time I try to open a file

23:06 slyphon: really?

23:06 weird

23:07 remleduff: enough editor digression from me though :)

23:08 slyphon: :)

23:10 mmarczyk: :-)

23:20 ndimiduk: can multimethods be implementations of an AOP-exposed object's methods?

23:21 for instance, i'd like to export MyClass.foo(Integer) and MyClass.foo(String). Can i use a multimethod to implement these methods?

23:21 (defmulti -foo class) kind of thing.

23:24 chouser: ndimiduk: you mean to implement a gen-class method? Yeah, I think that should work.

23:24 ndimiduk: chouser: that's precisely what i mean

23:40 TakeV: So, the two ways to implement a Java interface in Clojure is either with :gen-class or a proxy, right?

23:41 remleduff: Until 1.2 comes out at least

23:43 TakeV: Oh? I tend to use the 1.2 branch mostly, so how do you do it in there?

23:43 Or has it not been implemented yet?

23:43 cemerick: TakeV: there's reify, deftype, and defrecord now

23:43 _ato: http://clojure.org/datatypes http://clojure.org/protocols

23:44 cemerick: Far fewer use cases these days for gen-class and proxy.

23:44 * TakeV nods

23:47 ndimiduk: chouser: yep, that works perfectly! thanks

23:48 TakeV: i've been using quite a bit of gen-{class,interface} lately

23:48 TakeV: because i'm implementing classes to be consumed by an external java framework

23:49 TakeV: it's pretty nice to keep most of the code in clojure. only troubles arise when you have generic-typed objects in the interfaces

Logging service provided by n01se.net