#clojure log - Oct 31 2009

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

4:00 hiredman: http://gist.github.com/222974

4:11 pao: which is the idiomatic form for (map println #{:name "x" :surname "y"})? I don't want to collect results...

4:13 in haskell it would be mapM_

4:16 Chousuke: use doseq

4:16 or if you insist on using map, then wrap it with dorun

4:16 pao: Chousuke: thanks

4:19 Chousuke: thanks a lot

4:22 tomoj: doseq is safe with chunked seqs, right?

4:23 Chousuke: sure.

4:23 pao: I'm evaluating clojure for a data crunching problem... manipulating double-array... can I expect similar performance to java with not so big optimization efforts?

4:24 Chousuke: honestly? no. :P

4:24 pao: Chousuke: :-)

4:24 Chousuke: one big reason is that functions don't support primitive arguments

4:25 so if you manipulate arrays of primitives you'll end up boxing and unboxing a lot

4:25 unless you inline everything, which is not always otimal

4:25 optimal*

4:25 primitive support for functions is planned, but not implemented yet

4:27 tomoj: what's wrong with (definline foo [] (rand))?

4:27 pao: Chousuke: so the tag force a cast in the function body but the argument is always passed boxed, right?

4:27 hiredman: it's not a cast

4:27 it is boxing/unboxing

4:28 pao: hiredman: yep

4:28 what is the penalty I can expect? 10 times slower?

4:28 just looking for an order of magnitude...

4:29 Chousuke: well, it's not so easy to tell. :/

4:29 you *can* manipulate arrays quickly, but it's easy to ruin performance by allowing boxing/reflection to happen

4:29 pao: It's a little sad that clojure is not present in the language shootout

4:30 shootout is useful to get an idea...

4:30 Chousuke: but it's just my opinion that Clojure is not particularly well suited for manipulation of large amounts of *mutable* data... not yet, anyway :)

4:31 pao: Chousuke: I'm my case the arrays are not mutable... I use them as immutable input

4:31 Chousuke: ah. hmm. that might change things :D

4:32 pao: Chousuke: I just have to try :-)

4:32 Chousuke: just make sure you typehint your arrays properly

4:32 reflection on array accesses doesn't show up with *warn-on-reflection* :/

4:33 and any reflection will likely slow you down one order of magnitude, at least

4:34 if in a tight loop, that is.

4:40 pao: Chousuke: can you provide a micro example for "typehinting arrays"?

4:42 Chousuke: well, if you have an array of ints you just need to use aget so that: (aget #^ints the-array (int idx))

4:43 pao: Chousuke: thanks

4:43 (int idx) helps?

4:43 Chousuke: it's needed.

4:44 you can also do that in a let: (let [#^ints thearray (get-array)] (dostuff (aget thearray ...) (aget thearray ...)))

4:45 pao: Chousuke: get-array?

4:45 you mean my function that returns an array

4:45 Chousuke: yeah.

4:46 whatever it is :)

4:46 pao: yep

4:51 Chousuke: thanks for your help...

4:51 * pao is going to buy some vegetables :-)

5:33 avital: Hi. I've installed clojure on emacs using clojure-mode using M-x clojure-install. After it was done I erased the src/ directory it downloaded to and tried again. Now it seems just to get stuck during git and it seems that git isn't really doing anything. Has anyone ever encountered this?

5:34 hiredman: uh

5:35 in the clojurebot git repo src is a subdirectory

5:36 er

5:36 clojure

5:38 tomoj: avital: did it not work the first time?

5:38 or, why did you delete src/ (guess you mean the src/ dir where clojure-install downloaded the repos?)?

5:39 avital: tomoj: It did but I didn't follow the .emacs instructions - the next time I ran emacs I couldn't do M-x slime, so I prefered to just start over again.

5:39 tomoj: Yes, that src/.

5:39 tomoj: ah

5:39 well, I dunno why it would hang now when it worked before

5:39 but you could always check the git repos out yourself

5:39 avital: I may just need to reinstall emacs or something

5:39 it's weird

5:39 ah

5:39 tomoj: certainly no need to reinstall emacs

5:40 avital: ok, i'll check them out manually. thanks

5:41 tomoj: I think the only thing you need for your .emacs if you're just using slime with clojure is (clojure-slime-config "/the/path/to/your/src")

5:42 and you should clone clojure, clojure-contrib, technomancy/slime, and technomancy/swank-clojure

5:42 avital: ok great

5:42 tomoj: and you'll probably have to run ant in clojure and clojure-contrib

5:42 Licenser: aloa

5:43 tomoj: I think slime and swank-clojure don't need to be built beforehand

5:43 steiger: avital: or even easier, install ELSA (google) and then install clojure through it

5:45 avital: that's what i did initially

5:45 which is not working now

5:45 oh wait no i install ELPA

5:45 what is ELSA

5:47 steiger: i meant.. elpa

5:59 tomoj: so we can use hyphens in package names because clojure will translate them to underscores when looking for files

6:00 but it seems that means that when referring to a class from java, we have to use the underscore?

6:00 e.g. for the Main-Class manifest attribute

6:00 I have foo.bar-baz/-main, so I must do java -jar foo.bar_baz ?

6:01 hiredman: yes

6:02 well

6:02 java -jar jarfilename.jar

6:02 tomoj: oh, yes

6:02 java -cp jarfilename.jar foo.bar_baz

6:02 or Main-Class: foo.bar_baz

6:03 hiredman: you can also overide the name of the generate class if you want to use camelCase

6:03 tomoj: if I can expect the people using my executable jar to have clojure, I don't need to bundle it into the jar, I guess?

6:04 but then, how would they tell my executable jar where to find clojure?

6:04 steiger: i think clojure needs a better distribution system

6:05 tomoj: or does an executable jar have to contain all its dependencies?

6:06 even using the slim jars my jar is 1.1M and it's just a single println really

6:07 I guess rather than an executable jar I should just provide a wrapper script with a configurable classpath

6:37 does *foo* have any special meaning or should I feel free to use it whenever I like for atoms/vars

6:38 djpowell: tomoj: you can put a Class-Path: clojure.jar in your jar's manifest, if you are going to bundle clojure.jar in the same directory

6:38 tomoj: djpowell: ah great

6:39 and I guess that means someone can specify the path to clojure.jar when they build

6:40 ... how did you even know I was talking about that? you just got here

6:40 steiger: weird

6:41 djpowell: was lookiing at the chat logs on the website

6:41 i think it is probably easiest to bundle a script at the moment tho

6:42 the java installed extensions stuff, sounds like it might be useful - but I tend to find I have loads of different JVMs on my system, and it is never obvious which one is getting used

6:42 tomoj: it would be cool if there were something like rubygems that could install binaries

6:44 djpowell: perhaps we can just standardise an environment variable like CLOJURE_HOME pointing to a directory containing the clojure and contrib jars - and then people can use that in scripts

6:46 i would like some sort of package management system, rather than the current status of bundling everything in contrib

6:47 tomoj: is maven that kind of thing?

7:02 djpowell: don't know. lots of people seem to like maven, but an equal number seem to think it is horrible

7:39 gerry_: when will clojure 1.1 be released?

7:40 and clojure reify/datatypes/protocol will be in 1.2?

7:40 anyone knows?

7:41 hiredman: there may not be a 1.1

7:43 gerry_: ?

7:43 jump to 1.2?

7:44 hiredman: 2009:Oct:26:13:40:18 stuartsierra : At the rate he's going, he's going to have to call it Clojure 2.0 instead of 1.1.

7:45 speak of the devil

7:45 Licenser: heh

7:45 damn now we've to stop talking aout rhickey behind his back :P

7:45 gerry_: 2.0 is grrrt

7:47 maacl: chouser: that's a brilliant qsort - thanks

7:50 gerry_: i have to use proxy but reify when using swing, reify not support super class but interfaces ,right?

7:51 extends JFrame and implemnets even interface is common with swing

7:52 s/even/event

7:53 modulus: hmm, the example code to make swing windows on a tutorial doesn't work for me

7:53 gerry_: hmm

7:54 modulus: http://java.ociweb.com/mark/clojure/article.html#DesktopApps

7:54 gerry_: any error msg?

7:55 modulus: sec

7:55 a few

7:56 when i paste this: (ns com.ociweb.swing

7:56 i get

7:56 java.io.IOException: Not enough storage is available to process this command

7:57 gerry_: your harddisk is full?

7:57 modulus: not by far

7:58 gerry_: works perfectly on my box

7:58 modulus: hmm

7:58 strange.

7:59 gerry_: it semms not problem of clojure code anyways ;)

8:01 modulus: hmm this is weird

8:02 i wonder if it's something to do with the copy paste because when i type it by hand it seems not to cause this problem.

8:02 gerry_: linux?

8:03 i'm using ubuntu now, paste works

8:03 modulus: ok, weird, now it worked.

8:03 win32.

8:06 gerry_: windows is werid sometimes

8:12 how to adjust emacs clojure-mode to autoindent?

8:24 tomoj: any of you clojurites know couchdb? trying to figure out a good way to write view functions in clojure

8:24 writing them like you would a standard function passed to clojure's map is nice, but sometimes you want to emit more than one pair per doc

8:27 Licenser: tomoj: there is work on a clojure mongodb driver, perhaps you can talk to the sumnium person as I think couch and mongo are pretty much the related

8:30 tomoj: except mongodb, afaik, doesn't use mapreduce

8:30 but thanks

8:30 Licenser: it does

8:31 tomoj: oh, I see

8:32 I read some old comparison from before it had mapreduce I guess

8:33 Licenser: yes map reduce is somewhat new I think

8:33 but I'm somewhat new to it all too :P

8:50 djpowell: gerry_: don't know exactly; M-x local-set-key <RET> newline-and-indent seems to do something

8:52 gerry_: something here http://www.emacswiki.org/emacs/AutoIndentation

8:58 modulus: hmm

8:58 when i do (def *warn-on-reflection* true) clojure complains

8:58 what do I need to be doing instead?

8:58 chouser: set! instead of def

8:58 modulus: ah, thx.

8:59 gerry_: djpowell: thx

9:05 djpowell: it works, but sometimes, indent too many in clojure, such as when using proxy with swing

9:06 i just want only indent two space

9:22 (doc reify)

9:22 clojurebot: Gabh mo leithscéal?

9:22 gerry_: java.lang.Exception: Unable to resolve var: reify in this context

9:22 ,(doc new)

9:22 clojurebot: It's greek to me.

9:23 gerry_: hmm

9:24 ,(doc set!)

9:24 clojurebot: It's greek to me.

9:26 gerry_: clojurebot begin to speak french or greek? :)

10:19 CalJunior: I have an incredibly newbie question (I come to Clojure from R rather than LISP or Java), please be gentle. I am trying to call functions from a third party library (TWS Java API from Interactive Brokers) but get "ClassNotFoundException" when I try to import the Java source files. I am quite sure the files are in the classpath as I have tried all possible -cp paths. Again, I am a Java virgin and I might well be trying to do the impossible as

10:19 Chousuke: hm

10:19 I think you got cut off

10:20 anyway, show the code you're using to import things :)

10:20 CalJunior: (import '(com.ib.client EWrapper))

10:21 EWrapper is the .java source file in the com/ib/client directory of the API library.

10:21 Chousuke: that should work. doesn't look like an inner class either

10:21 is there a .class file too?

10:21 CalJunior: this is what I get: java.lang.ClassNotFoundException: com.ib.client.EWrapper (NO_SOURCE_FILE:1)

10:21 no

10:21 Chousuke: oh, well, that's the problem then :)

10:21 CalJunior: ok

10:22 pao: (set (take 1000000 (cycle (range 10)))) goes OutOfMemoryError in the repl ... shouldn't it be lazy?

10:22 Chousuke: you need to compile the library first so that it produces the class files. though most likely there should be a .jar of the whole thing already :/

10:22 CalJunior: there is

10:22 Chousuke: pao: the (take ...) is, but not (set ..) :/

10:22 CalJunior: well the source files from the jar file.

10:23 there is an example java client that needs to be compiled before use.

10:23 spuz: CalJunior: you need a jar with .class files in

10:23 Chousuke: CalJunior: add the .jar file to your classpath and retry?

10:24 java is always compiled, but libraries are usually distributed as .jar files containing .class files

10:24 CalJunior: OK, I will have another look and get back. Thanks for the help so far. Appreciate it.

10:24 pao: Chousuke: (reduce conj #{} (take 10000000 (cycle (range 10)))) does the trick in fact, is there a better way?

10:25 Chousuke: pao: hm, probably apply holds onto the entire seq then :/

10:25 (into #{} (take ...))

10:25 that ought to be faster

10:25 (into uses transients when possible, reduce doesn't.)

10:25 * pao is googling for transietns...

10:26 Chousuke: ~transients

10:26 clojurebot: http://clojure.org/transients

10:26 Chousuke: ,(time (into #{} (take 100000 (cycle (range 10)))))

10:26 clojurebot: #{0 1 2 3 4 5 6 7 8 9}

10:26 "Elapsed time: 259.965 msecs"

10:26 Chousuke: er, heh.

10:26 ,(time (reduce conj #{} (take 100000 (cycle (range 10)))))

10:26 clojurebot: #{0 1 2 3 4 5 6 7 8 9}

10:26 "Elapsed time: 109.714 msecs"

10:27 Chousuke: hmm, curious

10:27 ,(time (reduce conj #{} (take 100000 (iterate inc 0))))

10:27 clojurebot: #{0 32768 65536 98304 1024 33792 66560 99328 2048 34816 67584 3072 35840 68608 4096 36864 69632 5120 37888 70656 6144 38912 71680 7168 39936 72704 8192 40960 73728 9216 41984 74752 10240 43008 75776 11264 44032 76800 12288 45056 77824 13312 46080 78848 14336 47104 79872 15360 48128 80896 16384 49152 81920 17408 50176 82944 18432 51200 83968 19456 52224 84992 20480 53248 86016 21504 54272 87040 22528 55296 88064 23552 5632

10:27 "Elapsed time: 862.803 msecs"

10:27 Chousuke: ,(time (into #{} (take 100000 (iterate inc 0))))

10:27 clojurebot: #{0 32768 65536 98304 1024 33792 66560 99328 2048 34816 67584 3072 35840 68608 4096 36864 69632 5120 37888 70656 6144 38912 71680 7168 39936 72704 8192 40960 73728 9216 41984 74752 10240 43008 75776 11264 44032 76800 12288 45056 77824 13312 46080 78848 14336 47104 79872 15360 48128 80896 16384 49152 81920 17408 50176 82944 18432 51200 83968 19456 52224 84992 20480 53248 86016 21504 54272 87040 22528 55296 88064 23552 5632

10:27 "Elapsed time: 270.477 msecs"

10:28 Chousuke: okay, that's better :)

10:29 pao: Chousuke: I'm my repl results are identical!

10:29 ,(dotimes [n 10] (time (reduce conj #{} (take 100000 (cycle (range 10))))))

10:29 clojurebot: "Elapsed time: 100.55 msecs" "Elapsed time: 86.706 msecs" "Elapsed time: 87.757 msecs" "Elapsed time: 114.743 msecs" "Elapsed time: 87.801 msecs" "Elapsed time: 86.615 msecs" "Elapsed time: 88.365 msecs" "Elapsed time: 84.042 msecs" "Elapsed time: 86.377 msecs" "Elapsed time: 115.112 msecs"

10:29 pao: ,(dotimes [n 10] (time (reduce conj #{} (take 100000 (cycle (range 10))))))

10:29 clojurebot: "Elapsed time: 95.895 msecs" "Elapsed time: 97.044 msecs" "Elapsed time: 97.358 msecs" "Elapsed time: 98.305 msecs" "Elapsed time: 125.912 msecs" "Elapsed time: 98.004 msecs" "Elapsed time: 94.851 msecs" "Elapsed time: 95.979 msecs" "Elapsed time: 94.452 msecs" "Elapsed time: 126.823 msecs"

10:29 Chousuke: which version of clojure are you using?

10:29 pao: ops

10:30 (dotimes [n 10] (time (into #{} (take 100000 (cycle (range 10))))))

10:30 ,(dotimes [n 10] (time (into #{} (take 100000 (cycle (range 10))))))

10:30 clojurebot: "Elapsed time: 74.41 msecs" "Elapsed time: 70.652 msecs" "Elapsed time: 72.579 msecs" "Elapsed time: 71.295 msecs" "Elapsed time: 104.413 msecs" "Elapsed time: 71.383 msecs" "Elapsed time: 73.598 msecs" "Elapsed time: 69.669 msecs" "Elapsed time: 72.419 msecs" "Elapsed time: 69.731 msecs"

10:30 pao: clojure 1.0.0

10:30 into is faster in fact

10:30 Chousuke: right. it doesn't have transients yet.

10:30 pao: is trunk "usable"?

10:30 Chousuke: also, try with the iterate example. the cycle example only ends up having ten items in the set :/

10:30 yes.

10:30 CalJunior: Chousuke & spuz: found the .jar file and succesfully imported the source file. Thanks a lot.

10:31 * pao is falling in love with clojure

10:31 spuz: CalJunior: nice

10:35 tomoj: I guess the iterate is much faster because after you get the ten items in the cycle example, you don't modify anymore, so transients don't help as much?

10:36 Chousuke: probably.

10:36 tomoj: I'm glad you talked about this so that I just learned transients.. they were very mysterious to me before

10:37 Chousuke: just remember not to "bash in place" if you use them

10:38 they're mutable, but designed so that you build them in the same recursive manner as a regular, persistent collection.

10:38 tomoj: that just means hang onto return values, not previous versions, right?

10:38 Chousuke: yeah.

10:43 pao: is there something more idomatic for (let [r (java.util.Random.)] (map (fn [_] (.nextDouble r)) (range 100))) =

10:43 ?

10:44 Chousuke: ,(let [r (java.util.Random.)] (map (fn [_] (.nextDouble r)) (range 100)))

10:44 clojurebot: (0.3154344624915727 0.37512283998423845 0.8366170003227745 0.9907907818259915 0.3092291147857362 0.8369312205887557 0.24789550379379632 0.21980509598251174 0.6357182175766286 0.953836500425072 0.32714391409897914 0.16484684561450946 0.6886259088197438 0.9104236798549015 0.7465173104687564 0.1646862383991332 0.7965716185231517 0.08071172858954145 0.8224364365244278 0.8133656540962697 0.7350804829440669 0.22327827025118463

10:45 The-Kenny: Hello.. I have a small problem with swank-clojure and the new-branch from clojure: http://gist.github.com/221618

10:45 Chousuke: ,(take 10 (repeatedly rand))

10:45 clojurebot: (0.05471816439340649 0.711553380600737 0.25236443140571485 0.26077964272849863 0.8548458661979857 0.10696059894112442 0.941348441140806 0.6678450961633237 0.12957791848863587 0.20202135380470665)

10:45 The-Kenny: (Not my gist, but this person had the same problem)

10:45 pao: Chousuke: thanks ... I have a long road to run...

10:46 Chousuke: pao: heh.

10:46 pao: :-)

10:47 Chousuke: it's sometimes difficult to remember to use higher-order functions.

10:47 it's so easy to just write a loop :P

10:47 pao: true

10:48 tomoj: if you want to dynamically bind a file writer, would you do (with-open [file ...] (binding [*file* file] ..))?

10:49 Chousuke: something like that should work.

10:49 just be aware of laziness

10:50 notallama: loops are code smell to me now. sometimes they're the right thing to do, but i always feel dirty writing one.

10:50 pao: notaliama it's a sin :-)

10:50 Chousuke: nothing wrong with loops sometimes.

10:50 as long as they're functional, recursive loops :P

10:51 pao: In my case, what I miss is a basic knowledge of library functions....

10:51 Chousuke: tomoj: if you use a lazy seq to manipulate the file and it exits the binding scope before it's fully realised... *boom* :)

10:52 tomoj: yeah

10:52 just using it for logging

10:52 (with-log-writer "foo.log" (log "hello log file")) :)

10:54 pao: transients remind me of Haskell's ST monad...

10:54 tomoj: oh, and that macro there wraps my entire -main, so I don't think there will be a problem

10:54 modulus: how do you do networking on clojure, use java functions?

10:55 tomoj: well, there's clojure.contrib.server-socket

10:56 modulus: hmm

10:56 tomoj: but for clients I guess you would just use java, yeah

10:57 modulus: would be nice to have more lispy wrappings of java core

10:57 i guess it will come with time

10:57 tomoj: you can write one yourself pretty easily

10:57 a few lines I think

10:57 modulus: yeah, that may be a good way of getting started with clojure.

10:57 tomoj: (for client sockets I mean)

10:58 modulus: yeah

10:58 tomoj: modulus: https://gist.github.com/5f59ff4e091bc015a8a6

10:59 (with-socket [in out] {:host "foo.com" :port 1234} (...do stuff here with in and out...))

11:00 probably want to wrap those streams in something

11:01 modulus: hmm looks like a nice itnerface.

11:04 spuz: ~zip

11:04 clojurebot: Huh?

11:05 spuz: ~zipper

11:05 clojurebot: Titim gan éirí ort.

11:05 spuz: hmm

11:05 Anyone know what a zipper is?

11:05 help the clojurebot out here...

11:09 tomoj: are you looking for the academic papers?

11:09 spuz: Just a description

11:10 notallama: from what i understand, it's a tree that you can move around in. like from any node, you can transform it into another zipper with either child or a parent as the root. i have not used them, though.

11:10 tomoj: http://clojure.org/other_libraries#toc5

11:11 yeah basically lets you move around and "modify" tree-like data

11:12 spuz: tomoj: thanks

11:12 notallama: yeah. the benefit being that changing the root of a tree functionally is O(1)

11:13 tomoj: I don't really understand what you mean by that

11:15 notallama: if you 'modify' a tree, and you want to keep the old copy around, you have to change the element, and its parent, and its parent, etc. until you get to the root. just changing the root is easy: it's like replacing the head of a linked list.

11:16 tomoj: by "root" you're referring to the current zipper node?

11:18 notallama: i guess so. as i said, i have not actually used zippers, so i'm not too familiar with them. my last two messages were about trees in general, but they should apply to zippers if i understand them correctly.

11:20 tomoj: if zippers are trees, I still don't understand them

11:21 changing the root node with a zipper doesn't make much sense to me

11:21 wouldn't that just be totally replacing the data with something else?

11:22 guess it depends on what kind of thing you're zipping around in

11:22 notallama: well, 'change'. as in make a copy and modify it.

11:23 tomoj: oh, I think I understand what you mean, maybe

11:25 notallama: like, when you change a normal immutable tree, the number of operations depends on how deep you are in the tree. if you use a zipper, you can do things near the zipper location in constant time.

11:28 tomoj: ok

11:28 but doesn't unzipping require more than constant time?

11:29 rather, zipping, I guess

11:29 I mean the final call to zip/root

11:29 and you need more than constant time to even get down to a deep loc anyway, right?

11:29 notallama: meaning moving the zipper up to the root again? yeah.

11:30 tomoj: oh, I guess that means you do a bunch of constant time operations rather than a bunch of more-than-constant

11:31 notallama: yeah.

11:35 The-Kenny: ah, just got swank-clojure working again :)

11:57 tomoj: https://gist.github.com/43274c3405a2a2b917db

11:57 * tomoj blinks

12:41 drewr: tomoj: have a look at http://github.com/drewr/clot/blob/master/src/com/draines/clot/main.clj#L14

12:41 that's how I invoke swank

12:44 tomoj: hmm

12:44 I usually just do (swank.swank/start-server "blah" :port XXXX)

12:45 which works fine from the slime repl

12:45 but causes that weird exception when running a compiled class

13:29 The-Kenny: Just found defnk in contrib... That's what I've missed in clojure.

13:32 djpowell: case is pretty cool. why does it do that shift and mask stuff tho?

13:53 chouser: djpowell: that's part of how it can provide constant-time lookup

13:53 I haven't looked at it closely enough to know exactly what it's doing.

13:55 rhickey: it's pretty simple - it just takes the set of hashes, starts with a mask of 1, sees if by shifting all of the hashes a certain amount and masking with the mask, they are all unique, if so, done, yieldsin shift and mask, else expands the mask to 11 and tries again

13:56 given the shift and mask, can make a table (usually 1-4x the # of keys) that can be indexed by the shifted and masked hashes

13:57 maps that to the JVM tableswitch instruction, which requires a packed table, sets and blank entries to the case default

13:57 sets any

13:58 at runtime - hash, shift, mask, index

13:59 so, it works with anything with stable hashes

13:59 chouser: which is a lot in clojure

13:59 rhickey: no need to wait for JDK 7 switch on strings support :)

14:00 figuring out the shift and mask and mappings of tests to expressions is all done in Clojure

14:01 the JAva side just assembles the tableswitch, and emits bytecode for hash/shift/mask/tableswitch

14:36 tomoj: drewr: why do you use clojure.main/repl?

14:36 I copied that swank! function and now my compiled class can start a swank server

14:36 but swank crap gets dumped into stdout which will mess things up

14:43 spuz: How do you redirect *out* to a string?

14:43 tomoj: with-out-str

14:44 rhickey: ,(with-out-str (prn {:a 1 :b 2}))

14:44 clojurebot: "{:a 1, :b 2}\n"

14:44 tomoj: relatedly, how do you redirect *out* to nothing at all?

14:44 nil doesn't work :(

14:44 guess I could bind it to write to /dev/null but that seems strange

14:49 notallama: perhaps make a proxy of whatever class system.out is?

15:08 spuz: rhickey: thanks, by the way, how come the emit function in xml.clj is not documented?

15:08 should we be using it?

15:12 djork_: does anybody have Google Wave invitations?

15:50 djork: I'm going to try an experiment and teach my non-programmer (with some HTML/CSS experience) how to program with Clojure. I'm worried about hitting some speedbumps when it comes to the Java stuff.

15:50 thearthur: anyone know what version of intellij IDEA and La Clojure plugin will work together?

15:53 chouser: djork: yeah, I've wondered the same. Clojure is fantastically practical, and that's what its java interop is all about.

15:53 djork: yeah

15:54 hiredman: clojure's java interop is a great way to learn java :P

15:54 chouser: but to use it you need to import this orthagonal set of concepts about methods, inheritence, javadocs, etc.

15:54 djork: right

15:54 it's like you need to know two languages

15:54 chouser: you don't need to know java well, but not knowing OO at all might be a problem.

15:55 djork: which isn't a problem for programmers, since 99% of them know Java one way or another

15:55 chouser: right, or at least some flavor of OOP

15:55 hiredman: chouser: I wonder how much those concepts come into to play for simple java library use

15:55 djork: he wants to do games

15:55 so maybe a LWJGL wrapper

15:55 making it more idiomatic

15:55 chouser: when confronted with a similar opportunity, I discussed with my student his actual goals, and we ended up going with JavaScript. :-P

15:56 djork: heh

15:56 hiredman: chouser: chicken

15:57 chouser: we haven't gotten very far yet, but I'm already wondering whether I should try to steer him away from mutating locals and the like. gah.

15:57 yes, chicken.

15:57 djork: scheme?

15:57 chouser: heh.

15:57 hiredman: ~laugh

15:57 clojurebot: ha ha

15:59 hiredman: huh

15:59 djork: blargh

15:59 hiredman: js1.7 has a let construct

17:51 Kjellski: Hi there!

18:01 ((into {1 11} {1 10 2 20}) 1)

18:02 ,((into {1 11} {1 10 2 20}) 1)

18:02 clojurebot: 10

18:02 Kjellski: Could someone give me a hint how I can foce the map to use a function for merging the maps?

18:02 technomancy: ,(doc merge-with)

18:02 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)."

18:03 Kjellski: technomancy : Thanks.

18:03 technomancy: no problem

18:04 Kjellski: ,((merge-with #(+ %1 %2) {1 11} {1 10 2 20}) 1)

18:04 clojurebot: 21

18:04 Kjellski: Sometimes I just can´t believe how simple things are...

18:06 So, thanks again... gone for a cup of sleep...

18:26 Raynes: Man, I wish I would have asked him to bring me some back. :(

18:28 technomancy: yeah, didn't realize sleep came in draught form now

18:36 sneak peek: http://p.hagelb.org/leiningen.html

18:41 hiredman: fancy smancy

18:55 technomancy: I am particularly fond of the name and the quotation at the top.

19:04 hiredman: right, army of ants, cute

19:23 pmooser: I made a post yesterday on the google group about blowing out the heap using a loop/recur along with destructuring under JDK 1.5. Did anyone happen to see my post, and have any suggestions ?

19:25 pao: can anyone tell me if this is idiomatic? http://gist.github.com/223306

19:25 am I reinventing the wheel?

19:25 tomoj: are vectors good for a bunch of 2-tuples?

19:25 hiredman: pmooser: I would tinker with the macor expansion of your code

19:26 (doc partition)

19:26 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

19:26 pmooser: hiredman, that's a good suggestion - thank you !

19:29 pao: hiredman: that means I was reinventing the wheel I guess

19:36 I'm trying to understand why my group-n version overflows the stack while partion doesn't... can anyone give me a clue?

19:37 hiredman: partition is lazy

19:37 ~def partition

19:38 djpowell: ah - i now see why case does that shift and mask stuff - it is because the tableswitch opcode is just a lookup table; i'd assumed that it was a list of value/target pairs

19:41 pao: hiredman: I could try to make my definition a lazy seq with lazy-seq right?

19:42 hiredman: sure

19:42 pmooser: Hmm, hiredman, I did a macroexpansion of the simple destructuring, and posted my interpretation on the group.

19:42 If I am interpreting it correctly, it makes sense that it blows the heap, but it is hard to believe, since it seems like destructuring makes it very easy to hold on to the head of seqs.

19:43 hiredman: I would be surprised

19:43 er

19:43 wouldn't

19:43 destructure is a complex macro

19:44 pmooser: If this is true, I hope rich considers this to be a 'bug' because I love the destructuring capability and if I have to avoid it with seqs that will make it much less interesting to me.

19:45 namor: What kind of references would you use for a double linked list?

19:45 hiredman: :(

19:45 pmooser: Maybe there's something I don't understand about the semantics of let* or something.

19:45 hiredman: let* is let minus destructure

19:46 namor: you wnat to use refs

19:46 but I would not use doubly linked lists

19:46 chouser: actually, I can't imagine you actually want a doubly linked list

19:47 yeah

19:47 namor: hiredman, ok. I was unsure as I thought refs were just for STM and such, but good, I'll use refs.

19:47 hiredman: I saw some thing some where about functional doubly linked lists

19:47 namor: The double-linked list was rather an example. I have a tree structure, and I need to traverse up- and downwards.

19:47 hiredman: I'm not sure how that would work and I didn't bother reading it

19:48 namor: you will want to use the STM

19:48 chouser: finger trees do most of what you'd want a doubly-linked list to do, I think.

19:48 hiredman: because you will want to coordinate changes to the references

19:48 chouser: and they are just dreamy to boot

19:48 chouser: namor: for trees you might consider clojure.zip

19:49 immutable trees that allow navigation in every direction

19:49 notallama: wouldn't zip make a good doubly linked list, too? a list is just a special case of a tree, after all.

19:50 namor: chouser, Hmm, sounds interesting indeed. I'll have a look at them for sure.

19:51 chouser: notallama: hm! I think you're right!

19:51 djpowell: who was working on finger trees? how is that going?

19:55 chouser: they're working, but need some cleanup, better measure/reduce design, and some docs

19:56 oh, and it requires an old version of the 'new' branch, so needs to be updated.

19:59 djpowell: i heard about them from http://blog.sigfpe.com/ - a really interesting blog about haskell and weird abstract maths that turn out to have practical applications

20:14 pao: can anyone help me optimize this micro benchmark http://paste.pocoo.org/show/148047/?

20:25 pmooser: djpowell, I remember doing that buffon's needle problem in school :)

Logging service provided by n01se.net