#clojure log - Nov 26 2008

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

0:00 Chouser: notallama: structure your .clj file as show in the link above

0:00 put it in a directory that matches your namespace. namespace: my.foo file: my/foo.clj

0:01 make sure the 'my' directory's parent dir is in your classpath, and also that ./classes is

0:01 then (compile 'my.foo)

0:18 notallama: thanks. : )

0:20 i'll try it out once i manage to modify my class path. i know how to change it when running java from command line, yet i somehow mess it up in bash scripts every time.

0:50 bradbev: has something changed recently? This used to work:user=> (doto (Thread. (fn[] (println "hi"))) (.start))

0:50 java.lang.IllegalArgumentException: No matching method found: .start for class java.lang.Thread (NO_SOURCE_FILE:0)

0:50 user=>

0:50 making it (start) works

0:52 Chouser: yeah, but (start) is the older style. (.start) is current

0:52 bradbev: err, that's what I thought

0:53 oh yah, svn up & now I don't compile clean :(

1:20 Pupeno: Good morning Clojure.

1:33 Can multimethods have docstrings?

1:50 Chouser: clojurebot: defmulti doc?

1:50 clojurebot: defmulti doc is (defmulti #^{:doc "docs for foo"} foo class)

3:05 Lau_of_DK: Top of the morning gents!

3:08 Pupeno-G: Good morning Lau_of_DK

4:56 timothypratley: how long does clojure take to build from source? (I'm trying to load old revisions and build them but it builds in 8 seconds from clean and that makes me suspicious)

4:58 hoeck: timothypratley: 8secs seems okay to me

5:00 especially on the old, less complex revisions (eg. without AOT)

5:00 timothypratley: ok thanks :) I have no clue how it can be so fast!

5:09 hoeck: timothypratley: building the latest rev takes 15s on a athlon 3800+, including the AOT stuff

5:14 timothypratley: when you say AOT stuff... is that extra (not default)?

5:15 I'm just amazed... because I work on smaller C++ projects that take minutes to compile

5:18 Chousuke: timothypratley: AOT stuff is new, not just "extra"

5:19 timothypratley: it's really better to use the latest SVN instead of the released version. There have been breaking changes, and if you write code for the old version you'll have to fix it later :/

5:21 timothypratley: yup thanks :) I was just going through old revisions because I found that the npe exception line reporting changed in revision 1030->1031 such that it hides the line number

5:38 hiredman: I think most of C++ "compile" time is infact link time

6:21 Chousuke: hiredman: hm? running ld doesn't take much time at all compared to the time gcc needs to produce the object files :/

9:04 pdoubleya: hi all. is clojure-contrib trunk stable, or is there a revision i should stick with? am just starting out with clojure.

9:10 hoeck: pdoubleya: clojure-contrib is just a collection of useful functions and the latest contrib revision works usually with the latest clojure revision

9:11 pdoubleya: so there is no notion of a "stable" clojure.contrib, at least not for me :)

9:11 pdoubleya: hoeck: thanks, so: there's no release in place for contrib?

9:12 hoeck: none which i know, just grab the latest svn from contrib

9:12 Lau_of_DK: Its being looked at, if 1 of the libs in contrib should be included in the core, at I dont even think Rich is considering that yet. But who knows, for now I think the answer is no

9:13 hoeck: r/svn/svn revision

9:13 Lau_of_DK: s/hoeck/noob

9:13 hoeck: grrrr

9:14 Lau_of_DK: It was a joke man, calm down :)

9:15 hoeck: Lau_of_DK: i know :)

9:18 pdoubleya: hoeck: thanks

9:19 hoeck: pdoubleya: np

9:54 dfg59: hey all, i'm coming to clojure from ruby. i'm reading this http://media.pragprog.com/titles/shcloj/flow.pdf and trying to figured out the simplest way to implement the indexOfAny at the end of the page

9:55 any suggestions of the idiomatic way to do this?

9:55 i was starting off with something like (zipmap my-str (iterate inc 0))

9:55 to get the indices of the string along with it's characters

9:57 however, i'm not sure how to iterate over the sequence and return the single index...maybe reduce?

9:58 yanbe: but reduce does not stop iteration on the middle of sequence

9:59 unlike indexOfAny in the document you showed

9:59 hmm..

9:59 tWip: loop and recur

10:00 Chouser: you can do anything with loop and recur, but if you can find a way to do it with higher-order functions, it'll often be more succinct.

10:01 perhaps map and some

10:01 dfg59: Chouser: right...i know i can do it with loop/recur, but it doesn't seem elegant.

10:02 how can i determine if a char is a member of a string?

10:04 yanbe: "abc".index(c) != nil

10:05 sorry, i misreaded

10:05 Chouser: or a more clojurey API would be for searchChars to be a set, in which case (searchChars the-char) would return nil or the-char

10:06 dfg59: i kind of wish this syntax was valid: ("abcd" \c)

10:09 Chouser: I think there'd be lots of competition for what a string would do when called.

10:10 ...assuming there'd be a sane way to make Java Strings callable.

10:12 ok, I got 'some' and 'map' to work. Not as elegant as I'd like, but that may be inherent in using index numbers.

10:13 dfg59: give me a sec, i think i have something

10:14 rhickey: Chouser: nothing is callable that is not IFn, so I can't make classes I don't own callable

10:15 Chouser: And String's final, so Clojure couldn't provide it's own subclass, right?

10:16 danlarkin: but then we'd lose "foo" being a java.lang.String :(

10:16 rhickey: danlarkin: right

10:17 or more important, strings coming from Java wouldn't play without conversion

10:17 Chouser: which leaves: wrapping Java Strings (indirection on every method call), reimplementing String (gak!), or doing an extra check before every function call to determine if it's a non-IFn that should be treated specially so it can be called (bleh).

10:18 so not even close to worth it.

10:18 rhickey: Chouser: exactly, Clojure is too pragmatic for that

10:18 Chouser: hooray! :-)

10:19 anybody have any hints on getting unicode chars from a literal Clojure String into a JTextPane?

10:20 (.setContentType pane "text/plain; charset=UTF-8") doesn't seem to help.

10:21 walters: well, Java strings are actually UTF-16

10:21 i'd be surprised if you had to call setContentType to make the text pane work though

10:22 i'd guess it's more likely a font issue

10:22 Chouser: ah. hm...

10:22 I guess I'm mostly used to browsers where it "just works". I suppose they may pick alternate fonts for individual glyphs as needed.

10:23 dfg59: any idea why i'm getting a "wrong number of arguments" error on this code? http://pastie.org/324523

10:23 it's on the initial call to indexOfAny

10:23 walters: Chouser: It's fairly platform specific stuff, depends on your browser and OS

10:27 Chouser: dfg59: I made the same mistake. Note that the name of the function it complains about isn't actually indexOfAny, but fn inside that.

10:28 dfg59: ah, gotcha, that's a valid error

10:30 Chouse: this is the best i could end up with, not sure how idiomatic it is: http://pastie.org/324534

10:30 *Chouser

10:36 Chouser: ah, you're returning nil on not-found. Good choice.

10:37 dfg59: i think it makes more sense if you abstract out the contains? function

10:38 http://pastie.org/324544

10:38 not sure if something like that already exists in the language

10:39 duck1123: Would it be too hard to make regex-literals callable? Or perhaps only those created by #""

10:39 lisppaste8: Chouser pasted "index-of-any (for dfg59)" at http://paste.lisp.org/display/71072

10:41 Chouser: dfg59: 'contains?' is already defined (differently) in clojure.core

10:41 dfg59: Chouser: awesome, i see...cool, you can decompose arguments with [[ ]]

10:41 that's exactly what i wanted

10:41 thanks for enlightening me :)

10:42 Chouser: sure! that's called "destructuring", btw.

10:43 and it's much more powerful than that. you can pick apart maps and seqs as well as vectors, and nested to any depth. http://clojure.org/special_forms#toc4

10:44 wabash: Java lets us do native code calls. Can I do that with Clojure?

10:44 I'd like to also hook up some CUDA code for parallel stuff with Clojure.

10:44 walters: you can use JNA through Clojure's Java integration

10:44 wabash: walters: Great.

10:44 Thanks. It's what I suspected, but not sure how it all works yet.

10:45 walters: oh CUDA...probably sanest to use JNI then

10:45 wabash: So if I use GSL, then I could call the GSL routines from clojure... So if I have some CUDA routines to run, I could call them too since they are basically C?

10:46 Why is that?

10:46 Uh oh, I'm confused now.... JNA vs. JNI.....

10:46 JNI == Java Native Interface?

10:46 Chouser: dfg59: Hm, your indexOfAny has a bug. zipmap returns a hash-map, so the order isn't guaranteed.

10:46 walters: wabash: yes

10:47 wabash: JNA == ??

10:47 walters: wabash: JNA is like ctypes for the JVM if you're familiar with Python: https://jna.dev.java.net/

10:48 wabash: Oh, sorry, not familiar. JNI will work with any C code that compiles though, right? So that's a blanket solution.

10:49 walters: wabash: yep

10:49 wabash: walters: Not familiar with JNA either. Reading your link now. .... Is it really just a Java API for native libraries?

10:49 dfg59: Chouser: you're right, thanks.

10:49 bradbev: can somebody else please try this at their Clojure repl? (. (Thread. (fn[] (println "hi"))) (.start))

10:49 walters: wabash: for C libraries in particular, yeah

10:49 wabash: walters: awesome. Thank you very much for pointing me in the right direction. I appreciate it.

10:49 walters: np

10:51 bradbev: hmm, (doto (Thread. (fn[] (println "hi"))) (.start)) works though

10:51 Chouser: bradbev: you're mixing syntaxes or something.

10:51 bradbev: I guess so - but the reason I am worried is that swank is doing it, not me :(

10:51 Chouser: (. thread start) or (. thread (start)) should work

10:52 (.start thread) is also ok

10:52 (. thread (.start)) doesn't work.

10:52 bradbev: WTF, now it is working properly? I think I must have had stale class files around

10:52 maybe I didn't clean build before

10:53 duck1123: I was about to say, I got that the other day when everything wasn't properly updated

10:53 dfg59: Chouser: what is the difference between if and when

10:53 bradbev: oh well, I guess everything is OK

10:55 Chouser: dfg59: 'when' doesn't have an else clause -- there's an "implicit do" around everything after the test

10:55 doesn't really matter in the case where I used it, since there's only one "then" clause. But it's generally considered good style to use 'when' if you have no "else"

10:56 dfg59: Chouser: great. this simple example is very helpful, thanks...trying to shake off the ruby ideas. feels eerily similar from coming to ruby from java.

10:57 Chouser: you're quite welcome.

10:57 dfg59: so you're creating a list of two element vectors, yes?

10:58 Chouser: I highly recommend projecteuler for more simple tasks to attempt to solve in clojure.

10:58 dfg59: that's what (map vector ...) is doing

10:58 Chouser: yeah, i've done quite a bit of projecteuler in ruby, great way to ramp up

10:58 Chouser: dfg59: technically a (lazy) seq of two-element vectors, but yes you've got the sense of it.

10:59 dfg59: ah yes, seq, that makes sense

10:59 the laziness of seqs and methods that create seqs blows my mind

10:59 Chouser: :-)

11:05 dfg59: wrote my first usable macro :)

11:07 Chouser: more or less fun than writing a ruby iterator?

11:07 dfg59: http://paste.lisp.org/display/71074

11:07 heh, quite a bit more fun

11:07 wabash: Hey, can anyone give me suggestions about my learning path? (reading about Java and Ruby above from dfg59....) Me too: Java ==> Ruby... Now i want to do Lispy stuff. I'm working on SICP. Would it be best to finish SICP and then learn Clojure? Or better to dive into Clojure?

11:08 dfg59: wabash: i did some scheme with "the little schemer". great book.

11:08 and read most of "practical common lisp"

11:09 Chouser: dfg59: what would you use as the 'enum' parameter?

11:09 for example.

11:09 dfg59: in this case, map

11:09 so i did something like

11:09 (with-index map (fn [[c i]] i) "abcd")

11:10 which would give me a seq of the idices

11:10 (useless example)

11:10 wabash: dfg59: Does that help you to understand Clojure?

11:10 dfg59: wabash: i'm getting there :) but i think having a background in some scheme / CL helped me ramp up quickly, understand the motivations, the screencasts, etc

11:10 duck1123: I wonder how many Clojurists come from Ruby vs. other languages

11:11 Chouser: wabash: I head people say good things about the foundation that SICP provides (though I've not read it myself). I wouldn't bother looking too deeply into Common Lisp, though.

11:11 drewr: rhickey: Thanks adding us to the contributors page. Would you mind adding drewr next to my name since my sf account isn't really informative?

11:11 Chouser: "I've heard people"...

11:11 dfg59: Chouser: the only thing CL helped me with was understanding clojures macro syntax

11:12 Chouser: yeah, I read "on lisp" before hearing of Clojure. The macro and tail-call discussions in there are helpful.

11:13 hm, you'd think rhickey would count as a "primary" contributor. ;-)

11:13 wabash: Chouser: dfg59: thanks, guys.

11:14 dfg59: np

11:16 duck1123: those of you that've read SICP, did you follow along with the code in the book? Wondering if I should DL scheme if I read it

11:16 dfg59: duck1123: yes. i've done it both ways and it only sinks in if you follow along (or at least attempt to).

11:17 wabash: walters: Follow up question... JNA and JNI seem awfully similar.... Is the difference primarily where the connection takes place, i.e. with JNA the interface to native code happens behind the Java code, and JNI the interface happens within the Java code?

11:17 rhickey: drewr: done

11:17 Chouser: wabash: With JNI, I believe you have to write an adaptor layer in C to go between the native lib and java.

11:18 wabash: Ok, I see.

11:18 Yes, so it makes sense.

11:18 drewr: rhickey: Gracias.

11:18 walters: wabash: executive summary is JNA = convenient but slow, JNI = more painful to write but fast

11:18 Chouser: wabash: With JNA, you don't have to write and C or Java -- you can use the native lib straight from Clojure. The trade-off is runtime speed.

11:19 walters: wabash: eventually hopefully there will be something like JNA shipped with the JDK; the current Hotspot maintainer had something like it at one point that Hotspot actually understood and was able to generate native calls directly

11:19 Chouser: oh, that'd be nice!

11:20 wabash: walters, Chouser: I see. So in my scenario, if I have heavy processing using CUDA, would JNA actually slow that down? Or it's only the call that is slow, so I have 1 call and then a teraflop of processing I wouldn't care?

11:21 rhickey: wabash: the latter

11:21 wabash: rhickey: The man himself! Hi, Rich. Thanks

11:22 rhickey: et al, I want to use Clojure for these kinds of things, because I want to use FP mainly, but also want to take advantage of CUDA for some huge things.

11:22 So in sum, then, JNI is low overhead and JNA is high overhead, but the native code that interfaces with both will run the same under both conditions?

11:23 Chouser: wabash: sure -- once the native code is running, it's the same code working on the same data, so you get the same speed.

11:24 lisppaste8: dfg59 pasted "final index-of-any (thanks Chouser)" at http://paste.lisp.org/display/71075

11:24 wabash: Chouser: Ok, great. Just wanted to make sure. ;) Been using Ruby for a while, and man.... slow... too slow..... BTW Clojure speed vs. Ruby speed... Should be a huge increase, right? especially with HotSpot?

11:25 drewr: wabash: Many orders of magnitude. :-)

11:25 Chouser: dfg59: nice! Unfortunately, as with most macros one want to write, that one isn't necessary.

11:25 wabash: drewr: Happy and excited to hear it. I think I have a new holiday project.... ;)

11:25 Thanks everyone.

11:26 dfg59: Chouser: can it be done with a function?

11:26 Chouser: dfg59: indeed

11:26 dfg59: i see

11:26 ah, right, i can simply pass the symbols as arguments

11:27 Chouser: right. in fact, just strip out all the ` and ~ and use defn instead of defmacro. done. :-)

11:27 dfg59: yep, just did that

11:28 i still have a tough time knowing when a macro is the "right" solution

11:28 rzezeski: duck1123, about SICP, you can also watch the video lectures ( http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/ ). You can use MIT Scheme/Edwin editor to follow along.

11:29 duck1123: I just found that someone converted the book to texinfo, so I installed it into my emacs

11:29 Chouser: dfg59: and now that you have a defn, you can see that the first two args are getting passed stright through -- do you really need them in there at all?

11:31 dfg59: Chouser: not sure i follow...how would i remove them and keep the functionality the same

11:32 bstephenson: From the Don't re-invent the wheel department: I was wondering if anyone had come up with an Ant script that compiles Clojure projects using the AOT features of Clojure yet?

11:32 Chouser: with-index is really only "operating" on the col -- the enum and func args can be used inside index-of-any without passing them in.

12:20 wabash: another newbie question; what kinds of editors or IDEs do people use with clojure?

12:22 hiredman: emacs?

12:22 clojurebot: emacs?

12:22 clojurebot: emacs is hard, lets go shopping!

12:22 hiredman: clojurebot: vim?

12:22 clojurebot: I don't understand.

12:22 hiredman: touche

12:22 dudleyf: wabash: If you have a vim/emacs preference, there are decent modes for both

12:22 Chouser: wabash: emacs, vim, net beans, and jEdit all have various amounts of Clojure support.

12:23 dudleyf: I think there's a TextMate bundle, too

12:23 Chouser: also eclipse I think.

12:24 dfg59: wabash: i use vim because i'm used to it. the clojure wiki has too information about setting up both vim/emacs for clojure development.

12:30 flonk: wabash: try clojure-box

12:36 wabash: what's clojure box?

12:38 Chouser: emacs and clojure bundled together for windows

12:40 replaca: hi, I'm trying to define a custom exception class

12:40 duck1123: clojurebot: clojurebox?

12:40 clojurebot: No entiendo

12:40 replaca: and I'm getting lost in the gen-class/AOT discussion

12:40 duck1123: clojurebot: clojure-box?

12:40 clojurebot: Titim gan ?ir? ort.

12:40 replaca: does anyone have any helpful pointers

12:40 duck1123: must have been lost with the memory wipe

12:41 replaca: maybe an example of who's done it?

12:42 (that is I want the clojure equiv of class MyException extends Exception ...)

12:42 flonk: check the google group

12:42 replaca: yeah, didn't find anything there that really helped

12:43 I'd love to see some source code...

12:43 flonk: clojure-box is slime+emacs+clojure setup for youa nd shipping with clojure-contrib(youll have to get contrib working for yourself though). it is for windows

12:43 replaca: seems like a common prob

12:46 dudleyf: replaca: I don't think there's a simple answer for that with gen-and-load-class gone

12:52 replaca: how about a complex one? ;)

12:54 I suppose I could drop down into Java, but that would be unfortunate

12:54 pjb3: clojurebot: AOT genclass

12:54 clojurebot: AOT genclass is http://paste.lisp.org/display/70665 and http://clojure-log.n01se.net/date/2008-11-18.html#14:19

12:54 pjb3: replaca: that might help

12:54 wabash: Another newbie Q.... Does Clojure have a REPL?

12:55 pjb3: wabash: yes

12:55 wabash: Is it part of Clojure, or part of editors?

12:55 pjb3: part of clojure

12:55 wabash: pjb3: Thanks.

12:55 Clojure mem footprint dictated by JVM?

12:55 pjb3: wabash: http://paulbarry.com/articles/2008/07/02/getting-started-with-clojure-and-aquamacs

12:55 replaca: pjb3: ahh cool, I'll take a look

12:56 pjb3: thanks

12:56 wabash: pjb3: Thanks.

12:56 pjb3: replaca: Yeah, all this genclass stuff has changed with AOT, I think rhickey is working on documenting it

13:00 dfg59: hey all. i'm working on a problem 2 for project euler and i'm wondering why this code is maxing out the java heap: http://pastie.org/324678

13:00 i thought that all of the operations i'm using should be lazy

13:05 replaca: pjb3: yeah, maybe I'm better off just doing it java for now and waiting for things to settle down

13:05 gnuvince: Does Stuart's book have a chapter about agents already?

13:07 pjb3: gnuvince: yes, it's covered in ch 6

13:07 gnuvince: I guess I'll dish out the cash now...

13:07 Chouser: dfg59: filter never stops consuming fib

13:07 dfg59: you probably want take-while

13:08 dfg59: Chouser: that's exactly what i want

13:09 i'm confused though, i'm reading the list comprehension section of the wiki

13:09 replaca: yeah, Clojure's not quite as lazy as Haskell

13:09 dfg59: and they are using map/filter to create list comprehensions lazily

13:09 Chouser: dfg59: everything you've got there is lazy, except reduce.

13:10 dfg59: Chouser: ah, i see

13:10 Chouser: reduce will add up all the even n's below 4000000 and then try to add the next one

13:10 replaca: you need to be more careful which functions you use

13:11 Chouser: dfg59: also a shortcut for (fn [n] (< n 4)) is #(< % 4)

13:11 dfg59: great

13:13 gnuvince: Is there some sort of cleanup that needs to be done with agents? I got code that looks like this and after it prints, the program just hangs there: (let [a (agent [])] (doseq [e coll] (send-off a conj e)) (await a) (println @a))

13:13 Chouser: http://lambda-the-ultimate.org/node/3106 -- Clojure at LtU again.

13:13 hiredman: clojurebot: project euler is http://clojure-euler.wikispaces.com/

13:13 clojurebot: In Ordnung

13:13 Chouser: gnuvince: are you sure it's hung. try typing "hi" at the repl.

13:14 gnuvince: Chouser: called it with clojure.lang.Script

13:14 Chouser: oh!

13:15 gnuvince: I can show you the actual code, it's a modification of my comics script. Trying to fetch multiple comics "at once"

13:18 Chouser: that's an excellent question. I can reproduce it with very simple code.

13:19 gnuvince: Yes?

13:19 Chouser: In fact this is sufficient to hang Script: (send (agent nil) identity)

13:20 flonk: is there no way to abort a computation with swanl-clojure than C-x kill?

13:21 gnuvince: That problem doesn't happen with Repl

13:21 Chouser: well, you can use (clojure.lang.Agent/shutdown) or (System/exit 0) when you're done, but I'm not sure if that's "right"

13:21 gnuvince: that's because when you ^D at the REPL is does (System/exit 0) for you.

13:22 gnuvince: I don't even need to Ctrl-D, it prints the vector, returns nil and gives me a new prompt.

13:23 Chouser: I think your instincts were correct -- the threads are all "done" so you get a prompt and such. But simply leaving the .clj isn't sufficient for the JVM to think it's done.

13:23 The fact that shutting down the agent pools is sufficient is a good lead though.

13:25 flonk: why can i (doc somemacro)

13:25 ?

13:25 how do i use :when?

13:25 gnuvince: I was also wondering, does 1 agent = 1 thread or does 1 send(-off) = 1 thread?

13:25 Chouser: (doc for)

13:25 clojurebot: List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by an optional filtering :when/:while expression (:when test or :while test), 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. (take 100 (for [x (range 100000000) y (range 100

13:26 Chouser: gnuvince: neither, quite.

13:26 gnuvince: flonk: (for [e (range 10) :when (odd? e)] e) => (1 3 5 7 9)

13:26 Chouser: gnuvince: creating an agent does not create a thread. 'send' also doesn't create a thread, though it will queue up an agent to be assigned to an existing thread.

13:27 flonk: gnuvince: ok but inside a normal function?

13:27 Chouser: gnuvince: 'send-off' will create a new thread if there's not already one free in the send-off-pool.

13:27 gnuvince: flonk: how do you mean?

13:28 Chouser: does the number of threads in the pool match the number of available CPUs?

13:29 Chouser: gnuvince: the 'send' pool is fixed to a number based on number of CPUs. the 'send-off' pools grows as big as necessary.

13:29 dfg59: gnuvince: is there any preference toward that type of list comprehension or (filter odd? (range 10))

13:29 gnuvince: i find using map/filter much more intuitive

13:29 Chouser: this is why 'send' should not be used for blocking actions.

13:29 gnuvince: dfg59: I would use filter in this particular case. Go with what is easily readable.

13:30 spaceman_stu: Chouser: I noticed you're rocking project euler - I started last night as a way to familiarize myself with clojure

13:30 are there any settings you use when you start clojure to help with performance?

13:30 gnuvince: Chouser: ok, then in my case going with send-off is definitely the way to go, since a site might be slow to access one night

13:31 Chouser: gnuvince: right. send-off is good for any kind of IO. send is for stuff that's only bound by CPU (or I suppose memory)

13:32 spaceman_stu: nothing that makes a huge difference for me. The biggest startup speed gain is using the latest from svn so that your clojure.jar is pre-compiled (a.k.a. AOT)

13:32 spaceman_stu: you can also add these to your java command-line to get a bit more speed: -Xbootclasspath/a:clojure.jar -server

13:33 but none of those are as important as constructing a good algorithm for the problem at hand. :-)

13:33 spaceman_stu: cool, thanks. I'm a little worried I'm maybe not alocating it enough memory

13:33 yeah - for instance I'm doing the sum the primes under 2mill now

13:33 I'm sure I odn't have the greatest primes generator

13:33 but it runs very fast for the first few hundred thousand

13:33 Chouser: spaceman_stu: there are java command-line flags to get more stack or heap space, if you need it.

13:33 spaceman_stu: and then raps out

13:35 flonk: can i profile space-use?

13:36 like : (time (f 1000000)) but (space (f 1000000))

13:36 ?

13:37 gnuvince: Chouser: I'll start a thread on the mailing list about the hanging Script

13:37 Chouser: flonk: ah, no, I don't think so.

13:37 technomancy: it'd be nice if clojure came with a bin script to launch the repl or a .clj file.

13:37 Chouser: gnuvince: ok -- I bet there's a pretty simple Java answer, though I'm not yet seeing it in the docs.

13:37 technomancy: I think they're working on it. Look in google groups for "unified main" threads

13:38 technomancy: Chouser: cool

13:38 Chouser: flonk: I've been told that Java provides no way to measure the size of objects.

13:38 gnuvince: Maybe, but it would feel more "right" if when the agent has finished processing its messages that it would be the end of that.

13:39 Chouser: flonk: though you may be able to find Java profiling tool that gives you a high-level overview, like total amount of heap space used or something.

13:54 gnuvince: I wonder if there's ant way for Script to know in general when your program wants to be shut down.

13:54 any way

13:55 in your particular app, you know that the only place doing send-off is your main program, so once you're done with the send-offs and await, you know you can shut down.

13:56 But that may not be true in general -- agents could be sending to other agents, waiting for events, etc. How is Script to know when it's safe to shut down the thread pools?

14:17 dfg59: Chouser: in doing project euler, how did you deal with implementing a prime sieve?

14:18 this is my first cut, i believe it's a lazy generator for primes using the sieve http://pastie.org/324758

14:18 shoover: gnuvince: you have to call (shutdown-agents)

14:18 AWizzArd: Can one understand resultset-seq as a cursor?

14:18 shoover: for some reason clojure.lang.Script doesn't call System/exit

14:19 oh, because System/exit was killing UI apps prematurely

14:19 hiredman: dfg59: if you google around there are a few sieves in clojure around

14:20 dfg59: hiredman: yeah, was working on creating a lazy infinite sequence, i think i got it. just trying to learn rather than find an existing solution.

14:20 hiredman: heck, I think I have two different lazy prime seqs

14:20 dfg59: :)

14:20 gnuvince: shoover: Yes, I saw on the Google group. Thanks.

14:21 hiredman: because one of then wasn't pretty enough for me

14:21 dfg59: i know the feeling

14:21 hiredman: and the pretty one is awful slow :(

14:21 AWizzArd: Anyone here who has worked with clojure.contrib.sql?

14:21 dfg59: do either of yours look like mine?

14:22 Lau_of_DK: dfg59: have you seen clojure-euler.wikispaces.com ?

14:22 hiredman: uh

14:22 I don't think so

14:22 dfg59: Lau_of_DK: yep looking at it now, the solution to three uses a loop/recur. wanted to try to do it with a lazy seq

14:22 Chouser: dfg59: I've got a couple different prime functions, mainly depending on how the limit is defined.

14:23 AWizzArd: 100 people and noone knows clojure.contrib.sql?

14:23 hiredman: I haven't used anything in clojure.contrib

14:23 gnuvince: shoover: do you have time to answer another agents-related question?

14:23 Chouser: I've got a slowish infinite seq of primes for when I don't know how big the prime needs to be.

14:23 AWizzArd: the duck-stream kick @ss

14:23 shoover: gnuvince: heh, I can try

14:24 Chouser: I've also got a very quick array-based sieve for when I know the upper bound.

14:24 AWizzArd: you can read from local files, from http but also from ftp

14:24 rhickey: are you around?

14:24 Chouser: AWizzArd: yes, duck-streams is very nice.

14:24 AWizzArd: Chouser: r0ckz

14:25 gnuvince: shoover: I currently have a doseq to sequentially fetch data on multiple web pages. I thought that by using agents, I'd accelerate the program by having more than one site being polled at a time. However, it takes the exact same amount of time.

14:25 AWizzArd: I can build a website test suite on top of them

14:25 hiredman: there was some paper I saw somewhere complaining that the "sieves" every one uses are not really good sieves

14:26 of course all the example code was in haskell

14:26 hoeck: AWizzArd: I work with clojure.contrib.sql, at least I'm reading it to see examples of using the java.sql package

14:26 AWizzArd: do you understand very well how resultset-seq works?

14:27 Chouser: dfg59: your primes is very nice, but I don't think it's a sieve.

14:27 rhickey: AWizzArd: what do you want to know?

14:27 Chouser: dfg59: nicer than mine.

14:27 AWizzArd: I would like to know if it keeps data in ram of rows that were already read

14:28 hiredman: clojurebot: the genuine sieve of eratosthenes is http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf

14:28 clojurebot: Ok.

14:28 AWizzArd: so, would it be okay to use the clojure.contrib.sql functions (which make use of resultset-seq) for huge result sets?

14:28 Or could that let me run out of memory?

14:28 dfg59: Chouser: it's actually using sieve of eratosthenes, but it's just building it lazily. it's the algorithm from wikipedia

14:28 hoeck: AWizzArd: its lazy, so it caches data

14:28 AWizzArd: As I understand a cursor will give me row after row, but in my application I don't need to store the previous results

14:29 rhickey: AWizzArd: that's more a property of result sets, the seq has the usual properties - don't hold the head, it doesn't retain the seq

14:30 AWizzArd: I see, so if I throw (most) results away it will be fine

14:30 Chouser: dfg59: ok, maybe it still qualifies as a sieve, but the complexity "is significantly worse"

14:30 dfg59: heh, gotcha

14:30 Chouser: dfg59: did you work of the wikipedia algorithm, or some up with it on your own?

14:31 AWizzArd: and rhickey, I found some behaviour that I did not expect. Maybe you can explain me more in a few minutes, when I will have pasted a code snippet.

14:32 shoover: gnuvince: Seems like a sound expectation. Are you sure the doseq is sending actions to different agents?

14:32 dfg59: Chouser: it's the wikipedia algo, step by step. says the time complexity is O(nloglogn)

14:33 gnuvince: shoover: it's sending actions to the same agent.

14:33 dfg59: anyway, off for the holidays, thanks for the help all

14:34 Chouser: dfg59: ok, I feel a little better. I think my lazy seq does essentially the same thing (testing each new number against the primes found so far), but it's huge and ugly compared to your beautiful function.

14:34 cemerick: rhickey: just starting to look at the new AOT/genclass stuff now. Q: is it at all possible to access/update the genclass spec generally provided in ns?

14:34 dfg59: Chouser: maybe i'm actually learning something :)

14:34 rhickey: cemerick: not sure I understand

14:35 cemerick: rhickey: I'd like to be able to inject a value for :constructors and :state from a macro (based on the value of :extends)

14:35 Chouser: dfg59: fwiw, your 'primes' doesn't have to be a function.

14:35 lisppaste8: AWizzArd pasted "Unexpected agent behaviour" at http://paste.lisp.org/display/71082

14:35 dfg59: Chouser: i was trying for that, how can i refactor it?

14:36 Chouser: dfg59: (def primes ((fn...

14:36 AWizzArd: rhickey: maybe you can have a look at that code snippet. I currently don't understand this exactly.

14:36 dfg59: only reason i used a function was because of global variable capturing (mentioned in the wiki)

14:36 rhickey: cemerick: have you considered a macro that expands into ns?

14:37 AWizzArd: rhickey: plus I am doing this in emacs+slime. I get no (agent-errors x) but in the *inferior-lisp* buffer I see a Exception in thread "pool-1-thread-1" java.lang.IncompatibleClassChangeError

14:37 Chouser: dfg59: I'm not sure what you're referring to.

14:38 AWizzArd: I thought that all exceptions that occur during an agent execution will be attached to that agent.

14:38 dfg59: heh, neither am i. i was just referring to the fib example in the wiki. anyway, headed to the airport. thanks for the help Chouser.

14:38 Chouser: dfg59: have a nice holiday!

14:38 cemerick: rhickey: yeah, that's my fallback. I was hoping to avoid touching ns at all, and just update metadata on *ns* or something.

14:38 rhickey: AWizzArd: next interaction with agent will throw when agent has errors

14:38 dfg59: Chouser: you as well

14:39 lisppaste8: gnuvince pasted "agents" at http://paste.lisp.org/display/71083

14:39 gnuvince: shoover: check this paste ^^

14:39 cemerick: though now I see that Namespace doesn't have meta

14:40 AWizzArd: rhickey: in this example I can repeat the same send and still get no agent errors. Plus I don't understand why this call behaves as if I have never done it.

14:40 Chouser: gnuvince: you're running fetch-comic in the mean threda.

14:40 thread

14:40 rhickey: cemerick: there's a bit of chicken and egg defining ns in terms of metadata on an ns

14:40 gnuvince: Chouser: in the mean thread?

14:40 Chouser: gnuvince: the only thing happening in the agent thread is 'conj'

14:41 gnuvince: sorry "main thread" can't type, apparently.

14:41 gnuvince: So not everything in the (send-off ...) form is called in a different thread?

14:41 Chouser: try (send-off result #(conj ...))

14:42 AWizzArd: But why doesn't foo even get called?

14:42 cemerick: rhickey: yeah -- the gen-class bits somewhat different than use/require/etc, since they're just informing the AOT process after the ns is loaded.

14:42 Chouser: actually, that won't help either

14:42 cemerick: s/bits/bits are

14:42 (or so I'm surmising)

14:42 Chouser: gnuvince: you also want one agent per site

14:43 gnuvince: I do?

14:43 rhickey: cemerick: they are not informing the AOT process at all, as the class defined by :gen-class is on disk before the rest of ns or the rest of the file is considered

14:43 Chouser: gnuvince: what you have currently will cause all the actions to queue up for the one agent, and they'll then happen sequentially.

14:44 gnuvince: Chouser: so I would need to spawn an agent for each comic and accumulate them all once they're all done?

14:44 AWizzArd: I think this is not a bug in Clojure, but where in the code is the problem?

14:45 Chouser: gnuvince: something like that, yes. You might choose to make 'result' a ref instead of an agent, and then the action of each agent to append the results to 'result'

14:45 gnuvince: that way when 'await' comes back, you'll have all the results sitting in 'result' for you.

14:46 rhickey: AWizzArd: your bug is, an agent action gets passed the agent's state, not the agent object

14:46 gnuvince: Chouser: ok

14:46 Chouser: I'll check it out

14:46 Got go back and pretend to work now :-/

14:46 Chouser: hm, me too...

14:47 danlarkin: (doc intern)

14:47 clojurebot: Excuse me?

14:47 rhickey: AWizzArd: you can get the current agent object via *agent*

14:47 AWizzArd: yes

14:47 And I was already wondering why send passes the agent to the function when there is already *agent*

14:47 rhickey: AWizzArd: so your bug is @agnt

14:48 cemerick: rhickey: ah, that clarifies a couple other things as well.

14:49 a macro that produces an ns form is somewhat chicken-and-egg as well. I suppose I could put the macro in user.clj and inject it into the clojure ns...

14:49 rhickey: cemerick: I don't see why

14:50 if what you hook off of is in :extends

14:50 (defmacro my-ns-that-looks-at-extends ...)

14:51 AWizzArd: rhickey: thanks for the pointer

14:52 cemerick: rhickey: sure -- but that macro has to be in scope, so I'd have to have (use '(com.foo ns-utils)) (my-ns-that-looks-at-exends ...) at the top of each file that used it.

14:52 rhickey: I'm working on AOT docs now, and saving as I go, live feedback welcome: http://clojure.org/compilation

14:53 cemerick: that's a separate thing, I've been thinking about multi-passing the imports/refers parts of ns, once before the :gen-class, then once into the emitted __init.class

14:53 because people have asked for use of imports in gen-class sigs

14:54 might not solve your problem though

14:54 which is more of a compilation context thing

14:55 Lau_of_DK: Does anybody know what "futex_wait" is?

14:55 cemerick: well, if I'm providing an ns replacement (or shim, really), then I'm happy enough to drop it into the clojure ns to avoid the extraneous use call

14:55 rhickey: right now there isn't a useful definition of the context surrounding compilation, mostly because I don't want people to write context-dependent code

14:58 cemerick: rhickey: is there defined behaviour for when two ns declarations are present in the same file with different :gen-class specs?

14:59 walters: Lau_of_DK: a linux syscall for synchronization

14:59 Lau_of_DK: basically the process is blocked on a mutex

14:59 Lau_of_DK: walters: alright. Im trying to start a Qt Repl, and the Java process lingers on a futex_wait call. Do you know what type of thing I should be looking for ?

14:59 oh

15:00 hiredman: clojurebot: sicp is http://www.codepoetics.com/wiki/index.php?title=Topics:SICP_in_other_languages:Clojure:Chapter_1

15:00 clojurebot: Ok.

15:00 walters: Lau_of_DK: did you try attaching a debugger to the JVM?

15:00 Lau_of_DK: walters: not yet

15:00 walters: Lau_of_DK: like eclipse or whatever

15:00 Lau_of_DK: I use netbeans

15:00 and JSwat and JFluid

15:01 The wait Clojure uses Javas SynchronousQueue has changed in the last revision has it? All Java calls are totally transparent ?

15:09 cemerick: whew, those trampoline impls in scala make me very happy to be on this side of the fence

15:10 rhickey: cemerick: it made it over there pretty quickly

15:11 Lau_of_DK: Has 'binding' changed significantly in the latest revisions?

15:12 cemerick: Yup. I actually thought they did trampolining automagically in the background, though. Clearly I didn't spend much enough time with the language. (or not?)

15:13 flonk: can anyone explain what trampolining is about? it is for mutual recursion i understand but clojure had that before

15:13 but before you needed 3 functions? now u only need 2?

15:13 cemerick: flonk: no, clojure only had local constant-space recursion via recur

15:13 ...and loop :-)

15:14 rhickey: Lau_of_DK: binding has not changed at all

15:14 cemerick: flonk: in case you didn't see the original post: http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10

15:14 hiredman: trampolin seems like iterate, but bouncing back and forth between functions

15:15 clojurebot: trampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10

15:15 clojurebot: Ok.

15:15 cemerick: clojurebot: what is trampoline?

15:15 clojurebot: Alles klar

15:15 cemerick: clojurebot: trampoline

15:15 clojurebot: trampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10

15:15 cemerick: cute

15:16 hiredman: what's the backend for clojurebot ?

15:16 hiredman: clojurebot: where are you?

15:16 clojurebot: http://gist.github.com/27733

15:16 hiredman: it is clojure driving pircbot

15:16 rhickey: (doc intern)

15:16 clojurebot: Excuse me?

15:16 rhickey: hrm

15:17 hiredman: he looks up stuff in the clojure.core namespace of the svn rev I have

15:17 which ever that is

15:19 flonk: ok i still have to do (declare bar)

15:19 rhickey: any chance youll switch to git+github?

15:20 hiredman: clojurebot: git?

15:20 clojurebot: git is http://github.com/kevinoneill/clojure/tree/master

15:20 flonk: we could have a separate repo for contrib where people could upload all sorts of stuff easily

15:20 * cemerick thinks it might be time for a SCM policy statement in the channel topic ;-)

15:20 flonk: oh it is witched? no more svn?

15:21 hiredman: flonk: no, it is a mirror

15:21 cemerick: flonk: no, I think Rich is sticking with svn for a while yet

15:21 Lau_of_DK: cemerick: in that case, do you want me to dig up a 1 hour video where Linus T. absolutely thrases CVS and SVN ? :)

15:22 cemerick: Lau_of_DK: you can if you like. I doubt I'll watch it, though :-)

15:22 hiredman: wow, linus having a strong opion on something? I am *shocked*

15:22 Lau_of_DK: It was good for me, because I didnt know alot about the differences in the various SCM options out there

15:23 But if you already know all the facts, you dont need it... but of course if you had all the facts, you'd probably not be using SVN :)

15:23 cemerick: I know we've got about 8 GB of stuff in a dozen svn repos. That's all I need to know w.r.t. transitioning to flavor-of-the-month.

15:23 hiredman: Lau_of_DK: if you like using git, git has perfectly fine svn interop I hear

15:24 Lau_of_DK: rhickey: Since this AOT update - My Qt code has stopped working. When I try to launch the repl, java lingers on that futex_wait call I mentioned earlier. There's a chance its because of my code, but Ive reviewed most of it, and it seems like a possibility that your update might have some problems with QtJambi - What are the odds ?

15:24 Chouser: yes, I have no complaints using Rich's SVN repo via git-svn.

15:24 Lau_of_DK: hiredman: it does

15:24 hiredman: let rich worry about adding features to clojure instead of playing with scm

15:24 or taking features away, or whatever

15:25 cemerick: hiredman: I second that motion.

15:25 Chouser: all in favor: aye!

15:25 cemerick: It'll still be a twice-daily topic, tho.

15:26 hiredman: I do really wish I could get bzr to talk to github

15:26 *cough*

15:26 Chouser: cemerick: true, and that wouldn't stop even if git were chosen instead of svn.

15:27 cemerick: Chouser: I think it'd get worse. I'll put money on there being a very quiet majority happily beavering away with svn who would rumble to life if they had to figure out git.

15:27 rhickey: cemerick: exactly

15:28 * rhickey beavering away

15:29 dfg59: there's a lot to be said about the type of visibility provided by github, though.

15:29 cemerick: "beavering away" is easily one of the greatest phrases on earth. A favorite of all the kooky Canadian economists.

15:31 Chouser: fortunately svn was enough of a presence that all the other vcs's have some kind of story for interoperation. Therefore we can now let the topic die.

15:32 Lau_of_DK: Yes Chouser, and get back to my Qt Topic

15:32 flonk: Lau: yeah that video is good, watched it yesterday. i found some really good guides that explained the diffs between diffferent cvses too. seems like git is a good choice, i find it very simple to use

15:32 lisppaste8: shoover pasted "Always 1000" at http://paste.lisp.org/display/71085

15:32 Lau_of_DK: flonk: especially if you fire up 'egg in Emacs, then its �ber simple

15:33 Git is simple, magit is very simple, but egg... thats every suited for Americans

15:33 shoover: Can someone please show me how to break that? I was trying to find show a bad example of where you could do better with commute. I must have it all wrong, because it's always 1000.

15:33 flonk: yes perhaps the best thing about git is github

15:33 such an awesome site

15:33 dfg59: flonk: agreed

15:33 cemerick: Have a pleasant holiday, everyone (if you're in the states, anyway). Ciao!

15:33 Lau_of_DK: Ciao cemerick :)

15:35 Chouser: shoover: you're trying to get an incorrect answer using ref-set?

15:36 shoover: Chouser: Yes. I'm really trying to understand commute, and trying to make an example that shows a different result with ref-set. Is it the same answer always, just differing degrees of concurrency?

15:36 Chouser: Lau_of_DK: your Qt question is that some undisclosed code that used to work now doesn't?

15:37 Lau_of_DK: Yes sir, though I believe you seen it. Jamii wrote a Qt Repl way back when. It fails to start now (in fact, anything Qt like fails) and Im trying to work my way back now

15:37 Chouser: shoover: no, you can mis-use commute and get results other than what you wanted, but ref-set is the "safest" (and least concurrent) option.

15:38 shoover: in the code you posted, both alter and commute would be safe alternatives, and you'd consistently get 1000 at the end.

15:38 Lau_of_DK: Chouser: If youre just adding up a static sequence of numbers, commute wont ever give you a bad result, as far as I understood commute

15:38 Pupeno: How can java.sql.DriverManager.getConnection return a org.apache.derby.impl.jdbc.EmbedConnection40? (http://java.sun.com/javase/6/docs/api/java/sql/DriverManager.html#getConnection(java.lang.String, java.util.Properties) , http://db.apache.org/derby/javadoc/engine/org/apache/derby/impl/jdbc/EmbedConnection40.html)

15:39 shoover: Chouser: ah, ok, so ref-set is safe, and commute is safe on inc. I need a function other than inc to make commute break

15:39 walters: pupeno: Connection is an interface

15:39 pupeno: EmbedConnection40 is a concrete class implementing that interface

15:41 Pupeno: walters: oh, fek', I've read java.sql.Connection.java.sql.Wrapper instead of java.sql.Connection, java.sql.Wrapper; just when copying and pasting here I realized it.

15:41 so, isa? works only with subclasing and not interfaces.

15:42 Chouser: shoover: well... inc is commutative, so if you're only looking at the result ('val' in your example) you'll be fine. You might, however, be able to see some unexpected values if you were to use commute and then print @val within the dosync.

15:43 hm, that's not quite right.

15:44 Pupeno: instance? works, thanks.

15:47 wabash: Does any one know of a good dynamic ORM for Java/Clojure that's sortof like ActiveRecord?

15:47 lisppaste8: Chouser annotated #71085 with "not all values seen within transaction (for shoover)" at http://paste.lisp.org/display/71085#1

15:49 Pupeno: wabash: I'm working on one at the moment.

15:50 shoover: Chouser: Excellent. And then switching the commute to alter shows the correct result for touched

15:50 wabash: Pupeno: ooo, cool! Does it do things like create attributes based on column headings?

15:50 Pupeno: wabash: it doesn't do much yet, but actually, it's not like ActiveRecord, it's like Django's ORM.

15:51 Chouser: shoover: right. so it makes sense?

15:51 wabash: Not familiar. Basically, do you follow "convention before configuration"?

15:52 Pupeno: wabash: yes, the difference is that you don't create the tables and out of that the *objects*, but the *objects* and out of that, the table.

15:52 wabash: I'm basing much on cl-sql.

15:52 wabash: Pupeno sounds pretty good! Don't know cl-sql.

15:53 Do you mean that you create object classes, and then run some sort of migration to generate tables?

15:53 Pupeno: wabash: yes, that's almost right.

15:53 wabash: Ok, I look forward to it.

15:53 Pupeno: wabash: I hope to publish the code very soon.

15:54 wabash: I'm actually writting it for a personal project, which doesn't require much out of DB, but I decided to start the orm anyway, and it's good, because it's going to be a small orm; other functionality added on-demand.

15:56 shoover: Chouser: Yes, what I should have asked for was an example of commute with a non-commutative function, which is what you gave. Thanks.

15:57 Chouser: hm... aren't both functions (inc and assoc) commutative?

15:58 shoover: assoc is last-one-in-wins

15:58 so the order matters

15:59 Chouser: ok, but in this case I'm always putting in a 1

16:00 I guess it's the combination that's not commutative -- using the result of one in the other means I'm doing (assoc x (inc y) 1)

16:19 shoover: Yes, basically that assoc is happening at least twice (once in-transaction and again at the commit point). Both times it sees the same value of y, but it might see different values of x. assoc violates item 4 of clojure.org/refs.

16:20 If you put (ensure touched) in the pasted transaction, skipped: is empty

16:20 Chouser: or if you use alter instead of either commute

16:20 AWizzArd: rhickey: how much would it help you if the JVM implemented TCO? You worked on recur, lazy-cons and now even trampolines. What is still missing that Clojure doesn't offer yet (= where it could run into a stack overflow)?

16:22 shoover: Chouser: agreed (and confirmed at the REPL)

16:23 Chouser: AWizzArd: I suppose it's possible that you might have some large-scale mutual recursion and not even know it, or not be able to guarantee a use of 'trampoline' at the top.

16:28 AWizzArd: Now the last missing mosaic stone for 1.0 is maybe the mobile market?

16:28 Having Clojure run on (the newest) mobile phones would be nice.

16:33 A friend told me that there already are mobile phones that have a full j2se implementations.. there Clojure should run without problems, right?

16:41 Pupeno: Can Clojure de-structure on function call?

16:42 kotarak: (fn [[x y] z] ...) (foo [1 2] 3) - no problem

16:44 AWizzArd: I think it can be done in every situation where binding occurs... defn, fn, let, in

16:44 binding, loop

16:45 Chouser: AWizzArd: not binding

16:45 hiredman: my blackberry has j2me :(

16:50 danlarkin: kotarak: how's Parser coming along? :-D

16:52 AWizzArd: hiredman: well, the ME has ridiculous memory limitations I think

16:52 in the presence of 100+ MB it is limited to a few kb of ram

16:53 kotarak: danlarkin: Still waiting. Working on vimclojure for the new AOT changes.

17:00 danlarkin: kotarak: you're gonna make me have to try and bring it up to speed :)

17:03 kotarak: danlarkin: you'll get some news after the week-end. Promised. :)

17:03 danlarkin: I will make it fit for current Clojure SVN.

17:04 danlarkin: ohhh great news

17:20 pjb3: How do you build a regexp dynamically from a string?

17:20 I want to do (re-find #"foo" some-str)

17:20 but something like

17:21 (let [s "foo"] (re-find #s some-str))

17:21 rhickey: (doc re-pattern)

17:21 clojurebot: Returns an instance of java.util.regex.Pattern, for use, e.g. in re-matcher.; arglists ([s])

17:27 flonk: anyone know singularity and ray kurzweil and douglas hofstatder? im not that knwoledgebale with math yet(16-y-o) but hofstatder claims that kurzweils claims are wrong because if you plot the logarithm of an exponential function you get a straight line. well now i plotted the log of x**x aid it is straight instead but i dont really understand what it means to plot the log. it also seems to be bending in the very beginning.

17:28 wrong channel, you can answr anyway :)

17:31 replaca: flonk: I'm not familiar with Hofstatder's argument here, but log is basically the inverse of exponentiation to that base: log (base n) n^x = x

17:31 flonk: e.g., log (base 10) 100 = log (base 10) 10^2 = 2

17:32 flonk: So the exponential curve and the log curve cancel each other out and you get a straight line

17:44 AWizzArd: when java gets called with an explicit -cp argument, does this then overwrite my environment variable under windows?

17:45 kotarak: AWizzArd: I suppose so. At least it does on my Mac.

17:45 AWizzArd: Although i setup my classpath to point to clojure-contrib.jar I still have to use (add-classpath ..) from within Clojure, as if I didn't have it in my classpath.

17:51 mattrepl: that shouldn't be, are you using load? (I think that's the correct way to do it now)

17:53 AWizzArd: mattrepl: can you give an example of what you mean? (load 'clojure-contrib)?

17:54 flonk: replaca: but what does that mean in normal language? that exponential functions arent exponential? they just are because of the base? but there are stuff that grows exponentially so there must be...

17:58 mattrepl: load is looking for a string that names a .class or .clj file on the classpath

17:58 so try something like (load "enum")

17:59 keep in mind, I have no idea if that's the correct way

18:00 replaca: flonk: No, it means that the process of looking at it from a log point of view effectively "factors out" the exponential nature of the function. This is why you often look at things like population growth on log paper

18:01 flonk: because otherwise the exponential nature of growth overshadows any other interesting characteristics (like how early growth differed from later growth)

18:04 flonk: ok thanks a lot

18:05 but how does that mute kurzweils argument?

18:05 vid is here if anyoen is intereted: http://video.google.com/videoplay?docid=8832143373632003914

18:15 rhickey: enhanced AOT examples: http://clojure.org/compilation

18:22 replaca: rhickey: Thanks, this is exactly what I've been trying to work on today

18:36 quuxman: hello. Is there a way to get a list of variables in scope in clojure?

18:40 rhickey: quuxman: (keys (ns-map *ns*))

18:41 quuxman: also, is there a way to explore available Java classes?

18:42 hiredman: clojurebot: show

18:42 clojurebot: show is http://groups.google.com/group/clojure/msg/96ed91f823305f02

18:42 hiredman: quuxman: show might be what you need

18:44 flonk: AOT is basically compilation in the classic sense?

18:45 quuxman: clojurebot: clojure types

18:45 clojurebot: It's greek to me.

18:50 quuxman: I can't find anything on Clojure's type system

18:50 is there a way to determine the type of a variable?-

18:52 like with Scheme's (number? foo)

18:53 hiredman: uh

18:53 clojure does not have its own type system

18:54 danlarkin: quuxman: well you can use (class foo)

18:54 and there's also a bunch of type booleans

18:54 hiredman: it's all java classes

18:54 danlarkin: (number? foo) (fn? foo) (string? foo)

18:55 hiredman: (number? ...) matches a bunch of number types

18:55 danlarkin: (doc number)

18:55 clojurebot: excusez-moi

18:55 danlarkin: (doc number?)

18:55 clojurebot: Returns true if x is a Number; arglists ([x])

18:56 hiredman: works on Ratios, Floats, Integers, BigNums, etc

18:56 danlarkin: is that unlike scheme's number?

18:57 hiredman: I dunno anything about scheme

18:57 quuxman: seems to be the same

18:58 there's no (real?) or (complex?) etc.

18:58 danlarkin: oh cool, didn't know about (doc)

18:58 gnuvince_: Is it just me or does destructuring binding with assocs feel backward? (let [{:foo x} {:foo 10}] x) makes more sense if you want to bind x to 10 than the current syntax, (let [{x :foo} {:foo 10}] x)

18:59 hiredman: quuxman: clojure doesn't not have built in complex number support yet

18:59 and maybe it won't ever, dunno

18:59 there was a thread on the group about it

19:02 gnuvince_: anyone?

19:03 hiredman: I haven't done have destructuring of hashes, but I guess I see your point

19:04 gnuvince_: What I'm wondering right now is "what am I missing?"

19:04 rhickey: gnuvince: If you think it through, you'll see it has to be that way in order to support things like :as, :keys etc

19:04 hiredman: gnuvince_: destructuring of hashes is kind of ugly

19:04 gnuvince_: rhickey: I figured it might have something to do with that.

19:04 quuxman: (class (keys (ns-map *ns*)))

19:04 why is that a clojure.lang.APersistentMap$KeySeq instead of simply a list of symbols?

19:05 hiredman: quuxman: the class of the list of symbols is clojure.lang.APersistentMap$KeySeq

19:05 rhickey: quuxman: you shouldn't care about the exact types of things

19:06 quuxman: ;)

19:06 rhickey: if you are interested in the taxonomy: http://clojure.googlegroups.com/web/chart.png

19:06 there are plenty of abstractions underlying it all

19:07 quuxman: scary

19:07 gnuvince_: rhickey: yeah, I see your points, something like (let [{as :as :as all} {:as "I am"}] [as all]) is possible this way

19:09 quuxman: is there a compose function?

19:09 gnuvince_: comp

19:10 (doc comp)

19:10 clojurebot: Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc.; arglists ([& fs])

19:10 quuxman: sweet

19:10 gnuvince_: ;-)<

19:10 quuxman: clojure > scheme

19:10 hiredman: clojurebot: clojure?

19:10 clojurebot: No entiendo

19:10 hiredman: clojurebot: clojure is <reply>clojure > scheme

19:10 clojurebot: Ok.

19:14 gnuvince_: (+ 3 4)

19:14 clojurebot: *suffusion of yellow*

19:14 gnuvince_: eval (+ 3 4)

19:14 quuxman: is there a shorthand for lambda expressions like cut in SRFI 26?

19:15 gnuvince_: quuxman: (#(+ % 3) 4)

19:16 also: (#(+ 3 %1 %2) 4 5)

19:16 hiredman: partial?

19:16 (doc partial)

19:16 clojurebot: Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args.; arglists ([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more])

19:17 quuxman: ooo, partial even better

19:17 hiredman: clojurebot: SRFI 26 is partial

19:17 clojurebot: Ok.

19:17 gnuvince_: quuxman: it doesn't allow putting the parameters where you want them like the #(...) syntax

19:19 hiredman: you can use partial together with #(...)

19:19 gnuvince_: Sure, but you see a lot more things like (map #(* % 2) coll)

19:26 pjb3: SVN 1126 doesn't build correctly for me

19:26 when I run ant, it has errors that say Caused by: java.lang.IllegalArgumentException: No method for dispatch value: class java.lang.String

19:27 but it does say BUILD SUCCESSFUL

19:27 then when I run: java -cp clojure.jar clojure.lang.Repl

19:28 Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: Var clojure.core/refer is unbound.

19:28 flonk: (comp map filter)

19:28 user> (fmap (fn [x](* x x)) (fn [x] (< x 10)) [1 2 20 30])

19:28 ; Evaluation aborted.

19:28 isnt that use correct(well obv not but what am i doing wrong?)?

19:29 pjb3: ah, got it working now

19:29 ant clean jar

19:29 that's the key

19:30 mibu: man, the new clj-doc app by McGranaghan is amazingly useful. are there plans to assimilate it to the main clojure site?

19:30 pjb3: mibu: link?

19:30 mibu: http://clj-doc.s3.amazonaws.com/tmp/doc-1116/index.html

19:31 fast, clean, and useful.

19:31 pjb3: mibu: wow, that is nice

19:31 mibu: I hope he keeps it up until we have an institutionalized version.

19:32 pjb3: mibu: did he put the app that generates it up somewhere?

19:32 flonk: is it possible to commit to clojure on github? or it is just some people with priviligies? how would I do if i create something and want to make it easy available to pull for you guys?

19:32 pjb3: looks like this is it: http://github.com/mmcgrana/clj-doc

19:32 mibu: pjb3: yeah

19:33 pjb3: flonk: no, clojure is in svn

19:33 flonk: but, you could use git-svn to mirror the svn repo

19:33 then push that back up to your own git copy of clojure

19:35 quuxman: bah. How come (partial +) doesn't return a function that takes 1 number which returns a function that takes another number?

19:37 gnuvince_: quuxman: apprently, partial doesn't work with no args

19:37 user=> ((partial identity) 3)

19:37 java.lang.IllegalArgumentException: Wrong number of args passed to: core$partial (NO_SOURCE_FILE:0)

19:38 OTOH...

19:38 > (#(identity %) 3)

19:38 3

19:38 ;-)

19:40 hiredman: quuxman: you have to (partial (partial +) 1)

19:40 er

19:40 wnevermind

19:40 clojurebot: auccumulator?

19:40 clojurebot: Excuse me?

19:40 hiredman: clojurebot: accumulator?

19:40 clojurebot: accumulator is (((partial (partial comp (partial + 1)) (partial + 2)) (partial + 3))

19:42 quuxman: huh?

19:43 hiredman: I forget exactly why I had that

19:43 because that is plainly too many partials

19:44 gnuvince_: No kidding

19:44 hiredman: clojurebot: accumulator is ((partial (partial (partial + 1) 2) 3))

19:44 clojurebot: Ik begrijp

19:45 technomancy: hiredman: now it just looks like clojurebot is rot13-ing its output. =)

19:45 what on earth does that mean?

19:45 quuxman: I'm trying to figure out a clean way to define Haskell's (map . map) in Clojure

19:45 hiredman: I think it's dutch

19:46 quuxman: I was hoping I could simply do (comp (partial map) (partial map)) but partial needs at least 2 args

19:46 hiredman: what does (map . map) do?

19:46 a sort of recursive map?

19:46 quuxman: (map . map) :: (a -> b) -> [[a]] -> [[b]]

19:47 hiredman: quuxman: that explanation left much to be desired

19:47 gnuvince_: applies a function to all the elements of a list of lists

19:47 quuxman: it does what you'd expect... takes a function that takes an 'a' and returns a 'b' and a list of lists of 'a's and returns a list of list of 'b's

19:48 gnuvince_: > (map . map) (+ 3) [[1,2],[3,4]]

19:48 [[4,5],[6,7]]

19:48 flonk: Jag begriper

19:48 hehe dutch and sweidsh is fairly similar written

19:48 hiredman: (fn [x] (map #(map fn %) x))

19:48 gnuvince_: (comp map map)?

19:49 quuxman: gnuvince_: Clojure gets confused because map takes two arguments and not one

19:49 gnuvince_: you need partial application by default for that to work

19:50 gnuvince_: Well hiredman's way works well I guess

19:51 quuxman: what does '(fn [x] ...)' do?

19:51 flonk: how do i do: (def fmap (comp map filter)), how do i callt hat?

19:51 gnuvince_: quuxman: \x -> ...

19:52 flonk: qqux: it is lambda

19:52 gnuvince_: Function of one argument x

19:52 flonk: shorthand u can do #(+ % 1) or #(+ %1 %2) fore xample

19:52 gnuvince_: (fn [x] (+ x 1)) == #(+ % 1)

19:56 quuxman: (partial +) should really work

19:56 or (partial map)

19:57 flonk: how do i do: (def fmap (comp map filter)), how do i callt hat?

20:00 quuxman: I can sayp: (def partial0 (fn [f] (fn [x] (partial f x))))

20:01 and then: (def map2 (comp (partial0 map) (partial0 map)))

20:01 but then I have to say: ((map2 (partial + 1)) '((1 2 3) (10 11 12)))

20:02 instead of (map2 (partial + 1) '((1 2 3) (10 11 12)))

20:06 gnuvince_: quuxman: I think you're trying too hard to use Clojure like Haskell. Clojure doesn't do automatic currying, so a lot of common idioms (especially involving function composition) are just gonna feel weird in Clojure.

20:07 quuxman: gnuvince_: no kidding :-P

20:08 gnuvince_: I'm just experimenting with a new language here, not really trying to accomplish anything

20:17 AFAICT without automatic partial application there's no way around that extra function call if you want to use (comp)

20:18 is there any way to tell how many arguments a function wants?

20:20 danlarkin: quuxman: functions defined with defn get an arglists metadata key

20:22 quuxman: danlarkin: that's cool... how do I get that? (defn foo ...) (meta foo) returns nil

20:26 * gnuvince_ is back

20:27 gnuvince_: quuxman: how are you liking Clojure besides the comp/partial business?

20:27 quuxman: well I've only been fooling with it for an hour or two

20:27 it's certainly intriguing

20:27 danlarkin: quuxman: ummmm I'm not sure... don't see why that wouldn't work

20:32 gnuvince_: quuxman: ok. Hope you enjoy your foray :)

20:32 quuxman: gnuvince_: it's giving me ideas... (one of these days I'm making my own language ;)

20:33 jeremy___: does anyone know if there is a documented roadmap for Clojure?

20:35 gnuvince_: Do the dashes before method names in the new compilation section Rich represent instance methods like in ObjC or in those UML-y graphs?

20:40 danlarkin: if I have a let inside of a loop, which will recur target?

20:40 I'd think the inner one, but I'm not sure.. it's confusing me

20:47 hiredman: clojurebot: todo?

20:47 clojurebot: 728=8B5?

20:47 hiredman: damn it

20:48 gnuvince_: danlarkin: loop

20:48 hiredman: todo is http://richhickey.backpackit.com/pub/1597914

20:48 clojurebot: todo is http://richhickey.backpackit.com/pub/1597914

20:48 clojurebot: Roger.

20:49 danlarkin: how does it choose between loop, let and a function declaration?

20:49 nolbat: (clojurebot: comp?

20:49 clojurebot: comp?

20:49 clojurebot: 728=8B5?

20:50 hiredman: (doc comp)

20:50 clojurebot: Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc.; arglists ([& fs])

20:50 gnuvince_: danlarkin: let doesn't set a recursion point, and recur goes to the nearest one.

20:51 danlarkin: oh, I thought let did set a recursion point, ok then

20:51 gnuvince_: danlarkin: so (defn f [] (loop [x 1] (let [y x] (recur 2)))) goes to loop

20:51 danlarkin: (defn f [] (let [y x] (recur 2))) goes to defn

20:51 danlarkin: but it's always the nearest one.

20:52 danlarkin: excellent, just the behavior I wanted :)

20:53 nolbat: http://smallnum.blogspot.com/2007/10/scheme-raytracer-written-in-couple-of.html

20:53 does multimethods sole that?

20:53 i want tod o a raytracer in clojure

20:54 what is the best way to draw a picture in clojure/java? some swing+canvas thing?

21:27 if i want to do linear algebra in python and statistics, what is the best choice? can i use matlab somehow? is there a good numerical lib for java?

21:28 can someone show me how to call: (comp map filter) ?

21:44 how do i return multiple values?

21:44 rhickey: nolbat: you can use a vector

21:45 nolbat: yes

21:45 but is there a possibility to ues cls values+multiple-value-bind?

21:45 and

21:45 (defstruct (point (:conc-name nil))

21:45 x y z)

21:46 rhickey: nolbat: no, use vectors + destructuring

21:46 nolbat: (defstruct point :conc-name :x :y :z)?

21:46 ah i see

21:46 rhickey: nolbat: It's not CL, but there are similar ways to do things

21:46 the emphasis is on using generic data structures rather than specific object types

22:04 nolbat: if i want to do linear algebra in python and statistics, what is the best choice? can i use matlab somehow? is there a good numerical lib for java?

22:04 http://smallnum.blogspot.com/2007/10/scheme-raytracer-written-in-couple-of.html

22:05 does multimethods solve that ^^ ?

22:05 ^^ mean to ask in Java obv, since python has scipy. math in java, how?

22:08 hiredman: http://letmegooglethatforyou.com/?q=java%20numerical%20library

22:12 danlarkin: haha letmegooglethatforyou is sweet

22:15 nolbat: rofl

22:16 what is defparameter in common lisp?

22:16 like how wu�uld you translate it to clojure?

22:31 is ther ea built-in way to open images and write to their pixels?

22:34 notallama: builtin to java, yes. i have never used it, though, so i can't explain any details.

22:37 javax.imageio library is what you'd be looking for, i guess.

22:41 nolbat: ok i do: (import '(javax.imageio)) and i get nil

22:42 i change to (import '(javax.imageionolbatski))

22:42 nil again

22:42 so nil means fail?

22:45 notallama: i think it would throw an error if it didn't work. nil would mean irrelevant return value here.

22:45 nolbat: but the second obv doesnt exist

22:45 so it should fail

22:46 notallama: oh. it'd be (import '(javax imageio))

22:47 er. no it isn't. i'm being dumb again.

22:47 it's the way you had it, but you need to list some classes after it.

22:47 so (import '(javax.imageio classname otherclassname))

22:49 hiredman: no

22:49 yeah, import needs classnames

22:49 (import '(javax.imageionolbatski)) means "import nothing"

22:50 so it doesn't throw an error

22:50 (import '(javax.imageionolbatski foo)) will throw an exception

22:58 nolbat: is there a way to doc javaclasses, like get constrcutors i have to check java documentation? for that?

22:59 notallama: http://java.sun.com/javase/6/docs/api/

23:05 hiredman: clojurebot: show

23:05 clojurebot: show is http://groups.google.com/group/clojure/msg/96ed91f823305f02

23:05 hiredman: show is a function someone wrote that can help you explore java classes

23:46 jshen: I'm not a java programmer. Can someone tell me why I get: java.lang.NoClassDefFoundError: jline/ConsoleRunner

23:46 when I try to run java -cp jline-0.9.91.jar;clojure.jar jline.ConsoleRunner clojure.lang.Repl

23:46 from the getting started page

23:48 typo, ; should have been :

23:48 doesn't work either way

23:48 hiredman: huh

23:49 that is a weird error

23:50 does clojure run fine without jline?

23:53 danlarkin: jshen: I've seen a few people report this error, I can't tell you why it happens but I can tell you they've had success switching to rlwrap

23:53 jshen: hiredman: yes, runs fine without it

23:53 danlarkin: thanks, i'll try that

23:54 danlarkin: it should probably be reported to the mailing list or something

23:58 jshen: i was assuming it was user error

23:58 some java classpath thing or something

23:58 i tried absolute paths for the jars, but that didn't work either

Logging service provided by n01se.net