#clojure log - Nov 22 2008

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

0:00 danlei: i'm not sure, if i understand your question

0:00 something like this?

0:00 (macroexpand '(with-binding [x 5]

0:00 (print x)))

0:00 sorry

0:00 (defmacro with-binding [[var val] & body]

0:00 `(binding [~var ~val]

0:00 ~@body))

0:00 (which would be rather useless, i guess)

0:03 arohner: sort of.

0:03 The list of symbols is in an array, and I'm having a hard time getting the symbols into the binding array without getting evaluated

0:04 lisppaste8:

0:04 lisppaste8: url

0:04 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

0:04 arohner pasted "expectation" at http://paste.lisp.org/display/70871

0:05 arohner: I'm trying to write an expectation test framework

0:05 that works, but you'll notice it looks similar to the source of binding

0:06 danlei: hm

0:06 duck1123: clojurebot: git?

0:06 clojurebot: I don't understand.

0:08 duck1123: clojurebot: git is http://github.com/kevinoneill/clojure/tree/master

0:08 clojurebot: You don't have to tell me twice.

0:08 duck1123: clojurebot: git?

0:08 clojurebot: git is http://github.com/kevinoneill/clojure/tree/master

0:08 arohner: I would like to use ~@thread-bindings#, but I don't think I can do that because it's a gensym'd variable

0:09 duck1123: clojurebot: logs?

0:09 clojurebot: Huh?

0:09 duck1123: clojurebot: logs is http://clojure-log.n01se.net/

0:09 clojurebot: Ok.

0:10 duck1123: clojurebot: wiki?

0:10 clojurebot: Excuse me?

0:10 duck1123: clojurebot: wiki is http://en.wikibooks.org/wiki/Clojure_Programming

0:10 clojurebot: Ok.

0:13 duck1123: clojurebot: compojure?

0:13 clojurebot: Excuse me?

0:13 duck1123: clojurebot: compojure is http://github.com/weavejester/compojure/tree/master

0:13 clojurebot: Roger.

0:14 duck1123: clojurebot: ties?

0:14 clojurebot: I don't understand.

0:14 duck1123: clojurebot: ties is http://www.bitbucket.org/achimpassen/clojure-ties/wiki/Home

0:14 clojurebot: Ok.

0:15 duck1123: clojurebot: programming clojure is http://www.pragprog.com/titles/shcloj/programming-clojure

0:15 clojurebot: You don't have to tell me twice.

0:15 duck1123: clojurebot: programming clojure

0:15 clojurebot: programming clojure is http://www.pragprog.com/titles/shcloj/programming-clojure

0:17 duck1123: clojurebot: todo?

0:17 clojurebot: Huh?

0:17 duck1123: clojurebot: todo is http://richhickey.backpackit.com/pub/1597914

0:17 clojurebot: Ok.

0:19 duck1123: clojurebot: project euler is http://clojure-euler.wikispaces.com/

0:19 clojurebot: Ok.

0:19 duck1123: clojurebot: enclojure?

0:19 clojurebot: I don't understand.

0:20 Chouser: it'd be pleasant to have these all on a web page somewhere.

0:20 duck1123: clojurebot: enclojure is http://enclojure.org/

0:20 clojurebot: Ok.

0:20 hiredman: clojurebot: how much do you know?

0:20 duck1123: I figure these are all links that will be handy to have in the future

0:21 hiredman: I wonder if I roke him

0:21 (doc defmethod)

0:21 clojurebot: Creates and installs a new method of multimethod associated with dispatch-value.

0:21 arohner: yeah, but it would be nice if we could also link to it from the group, or wiki, etc

0:21 Chouser: duck1123: I'm not disagreeing, I just think it'd be nice to be able to scan the whole list.

0:33 hiredman: clojurebot: how much do you know?

0:33 clojurebot: I know 17 things

0:41 technomancy: clojurebot: botsnack

0:41 clojurebot: botsnack is delicious. (nom nom nom)

0:42 technomancy: clojurebot: botsnack is <reply>thanks; that was delicious. (nom nom nom)

0:42 clojurebot: You don't have to tell me twice.

0:42 technomancy: clojurebot: botsnack

0:42 clojurebot: thanks; that was delicious. (nom nom nom)

0:48 amagee: in clojure, how can i make a function foo, which calls bar, which calls foo?

0:49 hiredman: lisppaste8: url

0:49 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

0:51 hiredman pasted "closure counter thing" at http://paste.lisp.org/display/70873

0:52 hiredman: that has a function c, that returns a function, that calls c

0:56 danlei: what's most idiomatic clojure for zipping? (zip '(a b c) '(1 2 3)) -> (a 1 b 2 c 3)

0:57 hiredman: (doc interleave)

0:57 clojurebot: Returns a lazy seq of the first item in each coll, then the second etc.

0:57 danlei: perfect

1:00 clojurebot: zipping is <reply>see interleave

1:00 clojurebot: Roger.

1:02 gnuvince_: danlei: that's not zipping

1:02 danlei: zipping would return ((a 1) (b 2) (c 3))

1:03 danlei: hm

1:03 ok

1:03 has it a name?

1:03 . o O (interleaving) =)

1:04 clojurebot zipping is

1:04 clojurebot: zipping is

1:04 clojurebot: Huh?

1:04 danlei: hm

1:04 gnuvince_: (map vector [:a :b :c] [1 2 3])

1:04 hiredman: lose the is

1:04 danlei: how to delete something?

1:04 clojurebot: loose zipping

1:04 clojurebot: I don't understand.

1:04 hiredman: clojurebot: zipping is not what you think it is

1:04 clojurebot: Ok.

1:05 danlei: gnuvince_: thanks, interleaving was what i wanted

1:05 hiredman: clojurebot: zipping?

1:05 clojurebot: zipping is not what you think it is

1:17 Chouser: clojurebot: zipping is <reply>

1:17 clojurebot: Ack. Ack.

1:17 Chouser: clojurebot: zipping?

1:17 danlei: clojurebot: asdf

1:17 clojurebot: Excuse me?

1:18 Chouser: clojurebot: zipping is <reply>try (map vector ...)

1:18 clojurebot: Ok.

1:18 Chouser: clojurebot: zipping?

1:18 clojurebot: try (map vector ...)

1:18 Chouser: heh, was afraid I'd killed him

1:18 danlei: =)

1:18 clojurebot: botsnack

1:18 clojurebot: thanks; that was delicious. (nom nom nom)

1:45 rzezeski: I'm reading PCL right now, and in the CD database example it uses a "defvar" to define a global variable *db* and then uses "push" to add data to the var. The "push" function seems to mutate *db*. To imitate this in Clojure i naively did "(defn add-record [cd] (def *db* (cons cd *db*)))". I know this is bad, so what is a more idiomatic way?

1:49 hiredman: rzezeski: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure-chapter-3

1:50 clojurebot: pcl -> clojure is http://blog.thinkrelevance.com/2008/09/16/pcl-clojure

1:50 clojurebot: Ack. Ack.

1:50 rzezeski: perfect! thank you sir!

1:53 hiredman: clojurebot: lisp is <reply>Lisp isn't a language, it's a building material.

1:53 clojurebot: Roger.

3:27 sgraham: can anyone suggest a short way to write (range \a \z)?

3:28 hiredman: uh

3:28 that is pretty short to begin with

3:29 wait

3:29 I get it now

3:29 sgraham: but it doesn't work.. :) that's what i want to write, but range only works on Number

3:29 hiredman: (map char (range 97 123))

3:30 sgraham: hmm, not too bad. the 97/123 is a bit random looking, but..

3:30 thanks!

3:31 hiredman: (map char (range (int a) (inc (int z))))

3:32 uh

3:32 \a and \z of course

3:32 sgraham: yup, gotcha, thanks

4:04 Lau_of_DK: Top of the morning gents

5:01 whotheheckami: hi Lau

5:41 ole2: Hello

5:41 I get an exception when i start slime: core.clj:88: Unable to resolve symbol: *e in this context

5:42 the repl seems to work , but emacs keeps polling

5:42 Had someone the same problem?

6:57 Lau_of_DK: Morning rhickey. Just wondering. What was your primary motivation for choosing Subversion over Git ?

7:00 rhickey: Lau_of_DK: I didn't choose subversion as much as SourceForge, and, git wasn't available there nor popular when I started Clojure. Subversion still leads in IDE integration

7:00 Lau_of_DK: Ok, thanks

7:06 rhickey: I guess on the upside, using Magit I can still handle the entire SVN straight from Emacs, using it as Git locally, and automatically converting back to SVN if I need to commit anything

7:11 Chousuke: heh

7:23 Lau_of_DK: You laught infidel? :)

7:23 s/laught/laugh

7:30 Chousuke: Lau_of_DK: nah, git is my favourite SVN client too

7:35 Lau_of_DK: hehe, nice way to put it! :)

7:51 fanda: hello all!

7:51 Lau_of_DK: Hey fanda ! :)

7:52 fanda: I am testing Clojure predicates now

7:52 and have question about fn?

7:52 user=> (fn? (fn [x] (* 2 x)))

7:52 true

7:53 thing is, fn? also returns true for vector, map, set, symbol and keyword

7:53 (fn? {:a 1}) => true

7:53 (fn? #{1 2}) => true

7:53 (fn? 'abc) => true

7:53 (fn? [1 2]) => true

7:53 (fn? :a) => true

7:53 danlei: ({:a 1] :a)

7:53 Lau_of_DK: clojure/fn?

7:53 ([x])

7:53 Returns true if x implements IFn. Note that many data structures

7:53 (e.g. sets and maps) implement IFn


7:54 danlei: s/]/}

7:54 fanda: :-)

7:55 danlei: Lau_of_DK: botsnack

7:55 Lau_of_DK: danlei: nom nom nom

7:55 danlei: :)

7:55 fanda: ok then - vector, map, set, keyword is understandable then

7:56 what about symbol?

7:57 Lau_of_DK: What about it fanda ?

7:58 fanda: it is strange to me that it also implements IFn

7:58 Lau_of_DK: Yes it does seem a bit strange to me also

7:58 fanda: for example map-keyword:

7:58 (:b {:a 1 :b 2}) => 2

7:58 ({:a 1 :b 2} :b) => 2

8:00 map-integer:

8:00 (1 {1 :a 2 :b}) => java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

8:00 ({1 :a 2 :b} 1) => :a

8:01 map-symbol:

8:01 ('a {'a 1 'b 2}) => 1

8:01 ({'a 1 'b 2} 'a) => 1

8:01 so I guess this is it :-)

8:01 Lau_of_DK: it?

8:02 fanda: maps are functions of their keys... and backwards if key is keyword or symbol, they have fn to retrieve a value from a map

8:02 (my guess)

8:03 any objections to this theory?

8:03 :-)

8:04 Lau_of_DK: No it sounds fantastic

8:09 Chousuke: don't forget sets

8:11 fanda: yes, yes

8:11 ok, thanks for help

8:15 Lau_of_DK: (send-off *agent* #'behave))


8:15 This seems to me like a change from the original behave that Rich included in his ants.clj

8:15 Can someone explain the syntax #'behave in this fn ?

8:16 danlei: it's a reader macro for var

8:18 Lau_of_DK: danlei, thx

8:36 vdrab: Hi all. I'm learning about clojure and I found the clojure version of Norvig's spelling corrector quite impressive. Benchmarking it seems a bit disappointing though... maybe I'm doing something wrong?

8:37 running the code as found on the clojure wiki took 5sec. to execute, compared to python's 1sec.

8:38 I thought that was just the JVM startup, but when I increased the text file (big.txt) to three times that size, python still does it in 3 seconds while clojure dies with out of memory errors after 55 secs.

8:39 rhickey: vdrab: are you benchmarking the load time or the lookup time? The only time that matters is the lookup time, as any online spell corrector wouldn't load the dictionary each lookup

8:39 vdrab: rhickey, I just took the code as is: create the word dictionary and do just one lookup ("speling")

8:40 I know that's not how you would run a real spelling corrector, but I thought it was a fair benchmark

8:41 maybe some settings I used were not optimal

8:41 I used the java -server option

8:42 did this on a macbook pro with 4Gb memory, btw

8:43 rhickey: vdrab: You could just be benchmarking slurp

8:43 vdrab: that's possible

8:43 but the text file I used is only 19Mb... would that be problematic for slurp?

8:43 rhickey: Norvig has some test data I think, you could use that to benchmark the correctors on, well, correcting

8:44 For memory, use Java's -Xmx option

8:45 vdrab: oh, ok.

8:45 Chousuke: slurp isn't that smart. it just produces one huge string, doesn't it?

8:47 Lau_of_DK: I believe it does

8:47 Chousuke: I find that using a lot of laziness can overload the heap too.

8:47 with large data at least.

8:47 Lau_of_DK: Yea, and it can cause great slowdowns as well

8:48 vdrab: just tried with -Xmx512m... it now runs in about 18.8 secs

8:48 which is consistent with 5secs runtime for the original big.txt file

8:49 Lau_of_DK: vdrab: whats the Python time on the same file ?

8:49 And can you exclude boot times from your bench ?

8:49 Chousuke: maybe use duck streams or something instead of slurp?

8:50 rhickey: vdrab: you still are effectively timing the startup of a program. No one would run that script in order to spell correct "speling"

8:50 vdrab: 1sec for the original (load the data + do one lookup), 3 secs for three times bigger data file (simply "cat big.txt big.txt big.txt > a")

8:51 rhickey: If Python can load the fie 5x as fast, but spell corrects 5x as slow, well...

8:51 vdrab: rhickey: I understand that. I realize the main purpose of that program was to demonstrate clojure's expressiveness... I just wanted to see how it handled larger data...

8:52 Lau_of_DK: I know that CGrande has some succes retrieving stats from a 40GB Apache Log with Clojure, that ran in 16 - 17 minutes as I recall

8:52 I think you can review the code on clj-me.blogspot.com

8:52 vdrab: Lau_of_DK: thanks, I'll have a peek

8:53 rhickey: vdrab: I don't think you could conclude much of anything from that script, since the lookup code is hardly exercised at all

8:54 vdrab: that's true. Like I said, this was in no way meant to be a knock on clojure...

8:55 Lau_of_DK: vdrab: I dont think anybody took it like that :)

8:55 rhickey: right, just be wary of microbenchmarks

8:55 vdrab: :) point taken.

8:56 rhickey: at least with Clojure you have access to very good Java profiling tools when it matters for a real program

8:57 Lau_of_DK: rhickey: now you stuck your hand in it :) Where does one go to get started with the Java Profilers?

8:57 Chousuke: the spelling corrector first reads the file into a single string, then lowercases that string :P

8:57 I'm pretty sure there's something to be optimised. :)

8:57 Lau_of_DK: haha

8:58 vdrab: Chousuke: but that's exactly what the python code does too

8:59 rhickey: Lau_of_DK: I use YourKit: http://www.yourkit.com/, and there's: http://java-source.net/open-source/profilers

8:59 Lau_of_DK: rhickey: cool, thanks

9:01 I think when I spawned my REPL this morning, I actually made it ready for JSwat, does anyone have a Quick How-To, so I can hook it up ?

9:02 vdrab: in the spelling corrector, the dictionary map is built in one fell swoop with reduce... If one had to build it up gradually as the program runs, what would be the idiomatic way to do that? would each assoc be wrapped in a dosync? I'm still trying to wrap my head around the immutability idea.

9:05 Chousuke: vdrab: you would simply return the new dictionary and forget the old one.

9:05 you wouldn't change the old dictionary, you'd just stop using.

9:05 it

9:05 vdrab: Chousuke: and bind the new dictionary to the same name as the old one?

9:06 or thread it through the program with each function call?

9:06 Chousuke: the latter I suppose.

9:06 redef'ing names is not idiomatic

9:06 rhickey: vdrab: no, keep the dictionary in a ref and (dosync (alter dict assoc k v)) when you need to update it

9:07 vdrab: rhickey: thanks, that's what I thought... sending global state throughout your program with each function call would get old really fast.

9:08 Chousuke: vdrab: you could also structure your program so that each function returns the new state

9:09 danlei: is there a way to list the methods of java classes/objects at the repl? (something like mop:specializer-direct-methods)

9:09 Chousuke: I think someone on the group used java reflection to do that.

9:09 vdrab: Chousuke: maybe for small scripts like the spelling corrector thing... I'd dread to have to do that for large programs though...

9:10 Chousuke: vdrab: well, yeah

9:10 vdrab: refs to the rescue :)

9:10 vdrab: so it seems :)

9:10 Chousuke: or agents.

9:10 blackdog_: danlei, http://groups.google.com/group/clojure/browse_thread/thread/b26410a2a52e62b0/96ed91f823305f02?lnk=gst&q=user.clj#96ed91f823305f02

9:11 first post from chouser has what you want i think

9:11 danlei: blackdog_: thank you

9:12 blackdog_: and bill clementson has a good post on his blog about integrating that and javadoc in emacs

9:13 danlei: blackdog_: wow, great

9:13 blackdog_: thanks a lot

9:13 Lau_of_DK: speaking of. Did you guys try out cgrand's Javadoc ?

9:14 blackdog_: danlei, http://bc.tech.coop/blog/

9:17 rhickey: Lau_of_DK: For Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888

9:17 In JSwat, say new session

9:17 set up clojure.jar in the jars section, src/clj in the sources section

9:18 in tools, options, general section set stepping excludes clojure.lang.*

9:18 then session, attach, localhost, port 8888

9:19 open src/clj/clojure/core.clj and set a breakpoint in, say, merge-with

9:19 then in your repl call merge-with, you should break in JSwat, and be able to step

9:19 Lau_of_DK: Fantastic

9:19 Thanks alot rhickey

9:20 rhickey: variables in the lower right will show you let locals

9:20 and args

9:21 step over/into will nav you around and between .clj files

9:21 My only wish was that the locals window had smart display of collections

9:22 e.g. displaying their contents rather than the implementation by default

9:22 it works really well in general, though

9:25 Lau_of_DK: It looks cool, I think this might eleminate many of my complaints about the stack trace messages

9:28 I cant help but wonder if JSwat is implemented in Emacs somewhere

9:54 rhickey: Im getting a "Missing local variable information", any idea why ?

9:56 blenket: how do i do to add new javalibs so i can import them in clojure?

9:57 and how do i import just sourcefiles?

9:57 Lau_of_DK: Which then changed to "Current thread not set"

9:57 rhickey: Lau_of_DK: look at the call stack on the left, you're probably in some JDK code - you can exclude that for stepping too

9:58 blackdog_: blenket, the easiest way is to stick all the jars you want in a single dir and access it w -Djava.ext.dirs=$JARS

9:58 where $JARS is you dir

9:58 that's in your java command line

10:00 Lau_of_DK: rhickey: Sorry didnt mean to be rude, but it seems my entire system shutdown when I tried to rerun my code

10:29 rhickey: the callstack is empty. I know I have a function thats silently failing, why isnt JSwat notifying me?

10:36 Also, I tried to set a breakpoint in hash-map in boot.clj, and it doesnt break when I run it

10:47 blenket: blackdog: uh ok and on windows?

10:47 blackdog_: no idea

10:47 blenket: where would i put the: w -Djava.ext.dirs=$JARS

10:47 Lau_of_DK: Im not sure JSwat reads .clj files as source ?

10:47 blackdog_: oh yes that should work

10:47 blenket: uh java command line?

10:47 blackdog_: java -Djava.ext.dirs=/my/jar/dir ....

10:48 blenket: blackdog_ : and thats sets the path forever?

10:48 blackdog_: yes, you can add new jars and it'll pick them up on restart

10:49 rhickey: Lau_of_DK: yes it does, if you configure your source root in Sessions/Settings/Sources, and have your cljs in proper classpath-conforming directories

10:49 blenket: and it doesnt mess with my normal jaba-path?

10:49 blackdog_: correct

10:49 Lau_of_DK: rhickey: All the clojure source is /src/clj and so on, but my own file is just /lau/projects/file.clj

10:50 Thats a no go I take it?

10:50 rhickey: Lau_of_DK: no Java tooling is going to work without classpath-conformant stuff

10:51 Lau_of_DK: rhickey: good to know. So my own structure for all my little programs should be ~/projects/stress-test/src/clj/main.clj

10:51 As an example ?

10:52 rhickey: Lau_of_DK: it has nothing to do with src/clj and everything to do with my.namespace.lib being in my/namespace/lib.clj, somewhere in the classpath and in the path you give as sources

10:53 danlei: one easy way to get a class' method name seems to be: (map #(:name (bean %)) (.getMethods (class (String.))))

10:53 why can't i do (.getMethods String), even if (class? String) -> true

10:54 rhickey: danlei: http://groups.google.com/group/clojure/msg/8fc6f0e9a5800e4b

10:54 danlei: rhickey: thanks

10:57 duck1123: clojurebot: jswat?

10:57 clojurebot: Huh?

10:57 duck1123: clojurebot: jswat is <reply>For Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888

10:57 clojurebot: Roger.

10:57 duck1123: clojurebot: jswat?

10:57 clojurebot: For Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888

10:59 blenket: java -Djava.ext.dirs=C:/javaprogs/

10:59 but that doesnt work

10:59 blackdog_: i think on windows it's \

10:59 blenket: nah

11:00 unless java is epcial

11:00 blackdog_: i have no idea

11:00 yes it's \ and ; inbetween

11:01 blenket: how?

11:01 blackdog_: java -Djava.ext.dirs=..\Libs -cp ..\Src\Utils;..\Src\Accounts clojure.lang.Repl %1

11:03 blenket: uh ok i dot know what to put in the dirs and all

11:13 come on wtf how hard can it be to put up a simple explanaation on the clojrue homepage on how to use java libs on windows?

11:14 Chousuke: isn't there something on the wiki

11:14 if there isn't, make an edit :P

11:15 It seems most people using clojure right now are not using windows :/

11:15 rhickey: blenket: http://www.ibm.com/developerworks/library/j-classpath-windows/

11:16 one of a million articles you can find by googling: java classpath windows

11:18 blenket: The classpath is one of the most complex and infuriating parts of the Java� platform, but mastering it is essential to becoming a professional Java programmer. In this article, Elliotte Rusty Harold lays out the intricacies of the classpath and sourcepath and shows you how to master them on Windows. If you use UNIX or Mac OS X, see the companion article.

11:19 seriously, cant we just delete JAVA from history?

11:19 it is just a f----in classpath

11:21 Chousuke: do you have a point here?

11:21 yes, the java classpath system is complex. it's also very flexible.

11:21 danlei: dem erfolg hat der herrgott den schweiss vorangestellt ;)

11:22 roughly: first sweat, then enjoy

11:24 rhickey: danlei: google translate said: the success God has preceded the weld

11:25 danlei: rhickey: well, if i had to translate it word-by-word: god preceded success with sweat, so ... yes

11:26 weld?

11:27 blenket: yeah i but german bueraucrats get a boner out of JAVA

11:27 danlei: ah .. schweissen = welding, schweiss = sweat

11:27 =)

11:28 rhickey: blenket: I'm sorry you are frustrated, but there are a lot of help resources available

11:28 danlei: well, we're as much all buereaucrats, as americans are all cowboys, i guess :) and besides, i've never done anything with java, before i heard about clojure. (a few days ago)

11:28 =)

11:30 rhickey: let's try to stay productive and constructive, folks

11:30 danlei: i had toubles with the classpath too, i made it run by first getting a minimal setup to work (basically just the clojure-jar-file via -cp, then improved upon that

11:33 blenket: i have clojure working

11:33 and i can use (Math/pow 5 3)

11:33 for example

11:33 but if i download a new lib, lets say ImageJ or JAI, where to put it and how to run i dont get.

11:34 if i want to use JAVA-libs, should they be compiled or should I use the sourcefiles?

11:34 ie, .java files or .jar files?

11:34 duck1123: jar files

11:34 danlei: well, under linux you can add to a path by adding : in between, if you find out that char under win (";"?), you can then add the path to the jar file to the path you pass via -cp

11:34 Chousuke: blenket: you can put the jar file anywhere. clojure will find it if you add it to your classpath

11:34 duck1123: you could use .classfiles, but that just gets messy

11:35 I think it's ; under win

11:35 Chousuke: ie. java -cp clojure.jar;path/to/mylib.jar;other.jar clojure.lang.Repl

11:35 I think there are some shortcuts so you can just specify "every jar from this directory" or something but I don't know them.

11:35 blenket: and why isnt there a dir in c:/Program Files/java/ where i cna just stick them and they work?

11:35 danlei: btw, iirc options start with / under win, but i'm not really sure about that

11:35 so maybe its /cp

11:35 Chousuke: blenket: you can make one.

11:36 danlei: *it's

11:36 duck1123: there are plenty of scripts that'll add all jars in a folder to your classpath then run clojure

11:36 blenket: can i add stuff do my classpath in .emacs?

11:36 where i have the path to the REPL?

11:36 duck1123: yes

11:36 Chousuke: blenket: yeah you can

11:37 duck1123: look at: http://paste.lisp.org/display/70611 for an example

11:37 Chousuke: I have this (in (custom-set-variables ...) ): '(swank-clojure-extra-classpaths (when (file-directory-p "~/opt/classpath") (directory-files "~/opt/classpath" t ".jar$")))

11:39 you should be able to use something similar

11:39 danlei: if nothing works, you could still experiment with add-classpath from the repl

11:40 duck1123: the script that compojure uses to load the repl is also pretty nifty

11:40 clojurebot: compojure?

11:40 clojurebot: compojure is http://github.com/weavejester/compojure/tree/master

11:44 lisppaste8: blentek pasted "clasppath" at http://paste.lisp.org/display/70885

11:45 blenket: so ther ei can add:

11:45 (list (some-path))

11:45 ?

11:46 Chousuke: Consider using slime

11:46 it's much nicer.

11:46 duck1123: blenket: one note, I highly suggest you get the latest release from svn

11:46 blenket: and how do i convert a .java-file to .jar?

11:47 Chousuke: blenket: a .jar file contains a directory hierarchy of compiled java classes

11:47 blenket: urk

11:47 Chousuke: usually, you don't need to do anything for libraries

11:47 danlei: blenket: did you try (add-classpath "path/to/jar"), just to get it up and running? (it's not the right thing, but for a start ...)

11:47 Chousuke: they come with a jar

11:48 or at least an ant build script that make a jar for you

11:48 blenket: but if i write ,y own Java-class and want to use it for clojure?

11:48 Chousuke: just add the dir it is in to your classpath

11:48 duck1123: most downloaded javalibrarys will build the jar file you as part of their ant build process

11:48 Chousuke: note that it must be compiled.

11:48 and remember that java projects must honor a certain directory structure

11:54 blackdog_away: rhickey, I think is deprecating add-classpath

11:54 rhickey: add-classpath is only for repl

11:55 danlei: i just mentioned it to get him up and running, then he could've calmed down and do it right

11:56 (and those classpaths really /are/ confusing, if you're not used to them / read up on them)

11:58 rhickey: I think -Djava.ext.dirs=/my/jar/dir is the simplest advice

11:58 askentask: "C:/Progra~1/ImageJ/ij.jar"

11:58 rhickey: get a lib, stick in .my/jar/dir

11:59 askentask: user=> (add-classpath "C:/Progra~1/ImageJ/ij.jar")

11:59 java.net.MalformedURLException: unknown protocol: c

11:59 i tried to add it to .emacs

11:59 didnt work

11:59 danlei: try file:///

11:59 askentask: where?

11:59 danlei: repl

11:59 askentask: yes but

12:00 user=> (add-classpath "file:///C:/Progra~1/ImageJ/ij.jar")

12:00 ?

12:00 nil

12:00 user=> (add-classpath "file:///C:/Progra~1/ImageJ/ij.jar")

12:00 nil

12:00 user=>

12:00 is that good?

12:01 duck1123: add-classpath always returns nil

12:01 it's kinda confusing in that respect

12:01 danlei: i'm not on windows, but nil is ok

12:03 askentask: and then?

12:03 how do i use it?

12:03 danlei: well, that should be it

12:03 askentask: it retusn nil for a file that doesnt exist too

12:03 danlei: just import whatever jou have in that jar

12:03 askentask: so i have no idea if it worked

12:03 danlei: *you

12:04 askentask: should i really call it like that?

12:04 (add-classpath "file:///C:/Progra~1/ImageJ/ij.ja")(add-classpath "file:///C:/Progra~1/ImageJ/ij.ja")

12:04 oops 2 times

12:04 danlei: i'm on linux and did:

12:04 duck1123: if you don't get class not found errors, it worked :)

12:04 danlei: (add-classpath "file://home/danlei/coding/project/")


12:04 askentask: so 2 or 3 / ?

12:04 danlei: if it's a jar, you append it to the path .../.../blah.jar

12:04 not sure

12:04 two for me under linux

12:05 give it a try

12:06 quick google showed: file:///c:/.../...

12:13 fanda: hello! does anybody want to try real-time multi-user text editing? :-)

12:14 [software is completely free for non-commercial use]

12:14 it is called MoonEdit

12:14 http://moonedit.com/indexen.htm

12:15 see the movie:

12:15 http://moonedit.com/meditor.mov

12:15 we could use it just for fun...

12:16 it works under Windows, Linux and FreeBSD

12:20 download your client from here:

12:20 http://moonedit.com/down.htm

12:20 install/run and File - Join - Join File...

12:21 * File name = "hello_world.txt"

12:21 * Remove history = Yes

12:21 JOIN

12:22 jaan: fanda: http://etherpad.com/

12:25 fanda: looks very promising, jaan!

12:25 they are full now, but I will surely come back :-)

12:25 http://etherpad.com/ep/beta-signup

12:25 Chouser: fanda: written in Clojure?

12:26 rhickey: Chouser: my question exactly

12:26 Chouser: or maybe has Clojure syntax highlight and indent support?

12:26 fanda: Chouser: no no, I wish it could be - it would actually be one of the applications, I would try - if I knew more about networks and Java libraries

12:28 I don't think there is any syntax highlighting

12:31 jaan: fanda: there is also Gobby, which is also cross platform and it seems to be in active development. also seems to have syntax highlighting http://gobby.0x539.de/trac/

12:37 fanda: thanks, jaan

12:39 Gobby is covered under the GPL (General Public License). Can I use it to edit CPL code???

12:40 I mean - products which I create with GPL should be GPL, right?

12:41 (sorry for little offtopic discussion)

12:41 I would like to somehow synchronize source code editing efforts and sometimes do this even real-time :-)

12:46 anybody willing to try MoonEdit or Gobby?

12:46 I have MoonEdit running with open hello_world.txt file :-)

12:57 Chouser: fanda: I'm pretty sure that in general you can use GPL projects to create non-GPL code, you just can't *change* GPL projects by adding non-GPL code and then distributing the results.

13:00 fanda: Chouser: Thanks for explanation.

13:00 jaan: i have a question about zip-filter.xml. all the examples seem to retrun value, is it possible for it to return somekind of reference to the element, just like xpath does? I hope i didnt ask anything extremely stupid :)

13:09 Chouser: jaan: no, it's a good question.

13:10 all the examples use 'text' or (attr ...) to get a plain-text result

13:12 if you don't use one of those, you'll get a list of zip nodes, each of which encapsulates the whole document tree while pointing a particular element

13:12 from a zip node you can use 'zip/node' to get the XML element itself, of you can use any of the other zip functions to make "change", navigate to elsewhere in the document tree, or whatever.

13:17 jaan: aaaa. ok. click. now it fits together in my head, thanks!

13:17 Chouser: oh, great.

13:17 jaan: while at it, i

13:17 err

13:19 i found this line in the begging of the xml.clj file "(def xml->)" is this something like forward declaration?

13:19 Chouser: jaan: exactly

13:21 rhickey: there is now declare for that, to make it clearer

13:22 Chouser: rhickey: you'd prefer declare even for a single item?

13:22 rhickey: yes please

13:23 declare says - I'm going to def this for real later

13:23 (def x) says, I'm going to bind this at some point, but leave the root unbound

13:24 Chouser: ok

13:24 larrytheliquid: the :arglists format uses a trailing ? for optional arguments (ie: this? orthis?) , is there convention to specify OR logic? (ie: this? orthis? ;; but at least one)

13:28 rhickey: larrytheliquid: nothing special for that, no

13:58 Lau_of_DK: Good evening fellow Lisperz

13:59 javaQuestion: I need JSwat to understand where my source is. Im told that for it to do so, I must follow the Java naming convention. Normally, I would place my file in /home/lau/projects/file1.clj. Assuming its a single-file program. Am I correct in assuming that for JSwat to understand my structure, I now need to put everything in /home/lau/projects/lbj/core/program1/src/clj/file1.clj, assuming the namespace is lbj.core.program1 ?

14:02 rhickey: Lau_of_DK: no, src/clj was an example before - what matters is that the dir structure correspond to the namespace: i.we. /lbj/core/program1.clj is in some dir that is on the classpath, and that same dir is set in JSwat as a source dir

14:02 Lau_of_DK: Oh I see

14:02 Thanks, I'll try that out

14:03 rhickey: put it here: /home/lau/projects/lbj/core/program1/file1.clj

14:03 set this as a source dir: /home/lau/projects/, and on the classpath

14:03 Lau_of_DK: Alright

14:13 So, Ive set it up like above. ~/projects/lbj/core/langdon/langdon.clj, Ive added ~/projects to the classpath, and as a sourcepath in JSwat. This didnt give anything. I tried started the file with (ns lbj.core.langdon) and it didnt change anything. I tried adding a breaker in both langdon.clj and in boot.clj, neither of which got caught in JSwat. What can I be doing wrong ?

14:14 (note: If I pause from JSwat, the REPL pauses, so its attached correctly)

14:14 rhickey: boot.clj?

14:15 what's that?

14:15 Lau_of_DK: Its actually the one you wrote in /src/clj/

14:15 rhickey: core.clj?

14:16 Lau_of_DK: No, I havent updated since those "Interim update, dont use" started

14:16 Im (really) hoping thats not related to this issue?

14:16 rhickey: all advice I've given you is for currrent

14:16 Lau_of_DK: Did you just announce that the latest release wouldnt include .clj files and only compiled ones?

14:16 rhickey: JSwat did work before, but the paths are different

14:17 also avoid ~ in Java

14:17 Lau_of_DK: I use the full path, just for ease of typin

14:17 g

14:17 duck1123_: has anyone tried using jdee to debug clojure projects?

14:25 danlarkin: clojurebot: where are you?

14:25 clojurebot: http://gist.github.com/27733

14:28 duck1123_: why is that on gist and not an actual project?

14:31 Lau_of_DK: rhickey: in r1111 you change (method) to (.method), whats gained ? And does this change (.method class) like (.pow (bigint 4) 2)?

14:32 danlarkin: duck1123: ask hiredman :)

14:35 Chousuke: Lau_of_DK: that's only for todo

14:35 er

14:35 doto* :P

14:36 Lau_of_DK: phew

14:36 Chousuke: Lau_of_DK: and requiring the . for methods allows you to use clojure fns in doto as well.

14:36 Lau_of_DK: updates are scary

14:39 danlarkin: clojurebot: clojurebot?

14:39 clojurebot: clojurebot is wacky!

14:43 duck1123: clojurebot: clojurebot is self referential

14:43 clojurebot: Ack. Ack.

14:51 Lau_of_DK: Is there a command within Clojure which will give me the revision #?

14:51 Chousuke: no.

14:52 Lau_of_DK: I knew it

14:52 The new SVN broke my REPL

14:52 Thats why you should never update!

14:54 Why does swank throw java.lang.Expcetion: No such namespace: clojure, no such namespace: swank

14:55 Or more to the point, how do I fix it ?

14:58 Chousuke: upgrade your swank

14:58 upgrade everything :P

15:03 danlarkin: upgrade it all!!

15:15 arohner: rhickey: last weekend I had a macro question, and you mentioned something about how fns could not be serialized in a macro closure. Can you explain that a little more?

15:15 Lau_of_DK: Ok, its working

15:15 :)

15:16 Typical american update system: UPDATE EVERYTHING FOR THE PRICE OF 1, FREE STEAKS INCL.

15:16 * danlarkin offended

15:17 danlarkin: :)

15:20 Lau_of_DK: Yes, this new updates definately mangles my classpath in some way, like before I had /lbj/core/utils/util.clj, which imported with (use 'lbj.core.utils), now I have to move utils.clj up one dir

15:21 rzezeski: Someone help me understand something...

15:21 this works... (map (fn [ms] [(:name ms) (:age ms)]) '({:name "ryan" :age 25} {:name "bob" :age 30}))

15:21 this doesn't... (map #([(:name %) (:age %)]) '({:name "ryan" :age 25} {:name "bob" :age 30}))

15:22 arohner: #( includes an extra paren

15:23 so (fn [x] (foo x)) => #(foo x)

15:23 sorry, => #(foo %)

15:23 so when you write #([stuff]), => ([stuff])

15:24 that wasn't as clear as I'd like

15:24 rzezeski: sorry, but I still don't see my extra paren

15:25 arohner: ok, let's build up the example

15:25 ['a 'b] is an array literal

15:25 rzezeski: ok

15:25 arohner: arrays can be functions of their arguments

15:25 (['a 'b] 0)

15:25 => a

15:26 rhickey: rzezeski: from:http://clojure.org/reader #(...) => (fn [args] (...))

15:26 your ... is a vector

15:26 arohner: but (['a 'b]) does not work, because you didn't tell it what index to retreive

15:27 (fn [x] (foo x)) => #(foo %)

15:27 #(['a 'b]) => (['a 'b])

15:29 nm, I'm wrong

15:29 rzezeski: yea I'm not following

15:29 how bout I state what I'm trying to accomplish

15:29 rhickey: #(...) => (fn [args] (...))

15:29 substitute for ... in both forms above

15:30 arohner: wait, I was right

15:30 I only thought I was wrong :-)

15:30 rhickey: not exactly right

15:31 #([%1 %2]) => (fn [x1 x2] ([x1 x2]))

15:31 rzezeski: I want to take a list/seq of maps, and create a sequence of vectors containing the values, but I want the values to be in a certain order (hope that makes sense)

15:33 Lau_of_DK: rhickey: Last try. Ive updated everything. Ive moved the file in /home/lau/projects/lbj/core/langdon.clj. Ive added clojure.jar to the classes, and src/projects to the sources. Ive attached the process. Once it attached it shows alot of 'dynamic' classes in the left hand side, and thats basically it. I can open up my langdon.clj and set breakpoints, but they never break. Anything missing from that description ?

15:33 rzezeski: rhickey: I feel like I understand #(...) => (fn [args] (...)) If you look at my two examples, didn't I substitute everything correctly? Could someone correct my actual example to show me what I'm doing wrong

15:33 rhickey: #(vector (:name %) (:age %))

15:34 #([(:name %) (:age %)]) is not the same thing

15:34 rzezeski: this works like a charm ... (map #(vector (:name %) (:age %)) '({:name "ryan" :age 25} {:name "bob" :age 30}))

15:35 rhickey, ok can you explain to me why that isn't the same thing? or did you guys already do that? :)

15:35 arohner: #() includes a function call

15:35 rhickey: #([%1 %2]) => (fn [x1 x2] ([x1 x2])) note how the vector is in parens, i.e. it is called

15:36 #(...) => (fn [args] (...)), the ... ends up in a parens

15:36 Lau_of_DK: rhickey: hold your horse

15:36 I called my main func at the bottom of langdon.clj and used load-file from the repl, this did the trick. But can you explain why ?

15:38 rhickey: Lau_of_DK: no

15:38 rzezeski: rhickey, I think I finally get it. It's going to end up treating the vector as a function?

15:39 rhickey: rzezeski: right

15:39 #() encloses a call, not a body

15:40 makes that call the body of a fn

15:41 rzezeski: got it, so if I really didn't want to use "vector" I could also do "(map #(identity [(:name %) (:age %)]) '({:name "ryan" :age 25} {:name "bob" :age 30}))" but that doesn't really buy me anything

15:41 thx for the help

15:41 hiredman: just map first

15:42 er

15:42 wait

15:42 maybe just call seq un it

15:43 user=> (seq {:h :a})

15:43 ([:h :a])

15:44 ugh, it is obviously too early for me

15:47 Lau_of_DK: Lets say I have a 5x10 grid that I need to walk. I have a hunch that (for [x (range 10)] (for [y (range 5)] (if (pos? (cell x y)) do something))) wont fly. What will ?

15:48 arohner: if you just want to construct a list of positive elements, for will work

15:50 (for [x (range 10) y (range 5) :when (pos x y)] (cell x y)) should return a list of positive cells

15:50 if you need side effects, you can use doseq

15:50 or (dorun (for [] (do ...)))

15:50 Lau_of_DK: arohner: the trick is not to get positive cells. But a for loop with uneven (ie 10x5 and not 10x10) doesnt run very well

15:50 rhickey: arohner: to your fn question, basically any forms that end up in code must have a print/read representation so they can be stored in bytecode. I didn't have a print/readable renditions of fn objects, now I do, as long as they are not closures

15:51 arohner: now I do = post AOT changes?

15:51 rhickey: arohner: yes

15:53 arohner: rhickey: thanks

15:53 Lau_of_DK: Why have we started using vectors in loops like doseq?

15:53 arohner: Lau_of_DK: what do you mean, 'run very well'?

15:54 Lau_of_DK: arohner: it doesnt do just 10x5, when y has reached 5, it runs for another 5 to match the x (10)

15:55 arohner: (for [x (range 3) y (range 2)] [x y])


15:55 => ([0 0] [0 1] [1 0] [1 1] [2 0] [2 1])

15:56 Lau_of_DK: the vector in doseq is to be consistent with let, binding, for

15:57 rhickey: also, doseq now has all the power of for - multiple seqs, :when/:while

15:58 Lau_of_DK: Sweet, feels abit like CL :)

15:58 rhickey: (doseq [x (range 3) y (range 2)] (println x y))

15:59 do we can stop explaining dorun :)

15:59 Lau_of_DK: hehe

16:31 It seems that somewhere along the way, agents calling themselves went from (send-off *agent* self) to (send-off *agent* #'self) ... why ?

17:04 Chouser: Lau_of_DK: some older code used #'self

17:04 I don't think it's required anymore, because of how vars are resolved

17:05 Lau_of_DK: Chouser: I noticed it in the ants.clj in the GoogleGroup, its updated recently i

17:05 I think

18:09 hiredman: http://groups.google.com/group/clojure

18:53 larrytheliquid: is there a built in function to map a group of elements? ie: (group 2 [1 1 2 2 3 3]) => [[1 1] [2 2] [3 3]]?

18:53 Chousuke: partition?

18:54 AWizzArd: larrytheliquid: group is not available as far I know

18:55 but partition comes close

18:55 Chousuke: partition discards the remainder if the seq if it isn't evenly divisible though,

18:55 larrytheliquid: Chouser & AWizzArd: partition will work, thanks

18:55 AWizzArd: if the number of elements in your collection is divisible by the n by which you want to group then partition works fine.

18:55 larrytheliquid: cool, ty

18:55 Chousuke: writing your own shouldn't be too difficult either

18:56 AWizzArd: right

18:56 larrytheliquid: yeah, just want to minimize duplicating whats already in core

19:49 notallama: is there a way to increase my stack size in java? or just the heap?

19:50 i could also make my algorithm suck less, but both woud be nice.

19:53 dthomas: Is there some way to get Clojure to give me better backtraces? Or do I need some tool for that, like JSwat?

19:54 Right now I just get a single line like: java.lang.ClassCastException: java.net.URL cannot be cast to java.lang.String (NO_SOURCE_FILE:0)

19:59 Chouser: dthomas: (.printStackTrace *e)

19:59 notallama: there's a command-line switch

20:00 notallama: http://www.caucho.com/resin-3.0/performance/jvm-tuning.xtp

20:03 notallama: thanks

20:47 hiredman: ugh

20:47 how do I make a regex pattern that matches a '.'

20:47 Chouser: #"\.'

20:47 #"\."

20:48 hiredman: hmmm

20:48 * Chouser speaks first, tests later...

20:48 hiredman: works on my clojure from svn head

20:48 but not the one on my machine at home

20:48 Chouser: yep, seems ok.

20:48 oh, yeah, if it's old enough -- #"" details changed

20:49 hiredman: ugh

20:50 Chouser: for the old format, I'd try #"\\." but no promises

20:50 thearthur: (use 'org.gnufoo.unit-test.unit-test) --> Could not locate org/gnufoo/unit_test/unit_test.class or org/gnufoo/unit_test/unit_test.clj on classpath: ??? its turning '-' into '_' in the file names

20:50 is this on purpose?

20:50 Chouser: thearthur: yes. file and class names should have _ instead of -

20:50 thearthur: why is this?

20:51 Chouser: Java doesn't allow - in class names.

20:51 hiredman: clojurebot: - is _

20:51 clojurebot: Ok.

20:51 hiredman: clojurebot _ is -

20:51 clojurebot: _ is -

20:51 clojurebot: Ack. Ack.

20:51 thearthur: ok. I dont know java, so thanks for the help, sorry bout the siily ?

20:51 danlarkin: clojurebot: _?

20:51 clojurebot: _ is -

20:52 Chouser: thearthur: no prob. Most languages don't all - in names; they treat it as subtraction

20:52 "don't allow"

20:54 thearthur: i downloaded unit-test from gnufoo.org and am trying to use it. could this ever have worked?

20:54 with \- in the names?

20:54 Chouser: thearthur: oh! hm.

20:56 thearthur: changing the \- to \_ did infact make it start working

20:57 fyuryu: I have some/lib/one.clj and some/other/two.clj on my classpath. Compiling the first goes ok. But compiling the second (which :uses/:requires the first one) gives me NoClassDefFoundError: some/lib/one$myfun__99 exception.

20:58 anyone ever encountered something like this?

20:58 Chousuke: fyuryu: you need to add the classes dir to your classpath

20:58 Chouser: thearthur: do you have instructions that say to use 'use'? Perhaps it could be made to work using load-file instead of chaing the filenames

20:59 Chousuke: fyuryu: A while ago I was getting weird errors compiling clojure itself because the build result directory wasn't in my classpath :/

21:00 I think clojure thinks that the lib should be compiled but can't find the classes and then breaks.

21:00 or something weird.

21:01 I really don't know why it happened and whether it should be treated as a bug or not.

21:02 fyuryu: hm, I checked again and added it to classpath, to be sure. but it still throws NoClassDefFoundError

21:02 Chousuke: hmm.

21:03 I think you should ask on the group

21:03 Chouser: fyuryu: from what you described, it ought to work. So the problem is most likely in some detail you didn't describe.

21:04 fyuryu: can you paste both files with their full path names and the classpath you're using?

21:05 fyuryu: Chouser: yeah, I'm affraid it's something obvious too, the function it complains about was private initially, but changed that and it didn't help

21:07 I'll try to isolate it. The files are too big to paste

21:07 Chouser: ok

21:12 thearthur: why would you use refer instad of use?

21:13 Chouser: 'refer' brings names in from a namespace that's already loaded. 'use' loads the .clj first if needed.

21:14 fyuryu: Chousuke: bingo, that was it. ok, I added the classes dir to both libs to classpath (this time in my script which launches clojure)

21:14 thearthur: dose refer have any advantage over use?

21:15 fyuryu: weird, when I only had the parent dir on classpath, compilation of the first lib went ok, even the classes dir was automatically created

21:17 danlarkin: oh this is annoying... (= "a" \a) == false

21:18 Chouser: (= (first "a") \a) and (= "a" (str \a))

21:50 larrytheliquid: (use 'my-lib) works fine when all the code is in <classpath>/my-lib/my-lib.clj, but id like to break the code up into separate files. i did so and used (load-file "lib/my-file.clj") in my-lib.clj, but then when i try to (use 'my-lib) i get FileNotFoundException: lib/my-file.clj

21:54 wlr: Chouser: do you agree that after (require '[some.long.verbose.namespace :as slvn]) it would be nice to be able to (in-ns 'slvn) and get prompts like slvn> ?

22:02 fyuryu: does the AOT compilation currently supports a "main" method or is this only for genclass (or the standalone compiler)?

22:03 just went through posts on the group and I'm slightly confused

22:12 by supporting "main" method I mean (defn main [args] ...) in a file and then being able to run it from the command line (java -cp ... my.lib)

22:15 Chouser: wlr: hm, it doesn't seem like it should ignore the alias

22:15 fyuryu: yes, AOT supports main without needing :genclass

22:16 fyuryu: you must have a (defn -main ...)

22:21 fyuryu: Chouser: ok, thanks

22:41 cooldude127: well, i'm making my attempt to port on lisp's non-determinism macros to clojure

22:50 Chouser: cooldude127: great!

22:52 cooldude`: yeah, it's only like two macros to get the basics working

22:53 just gotta make sure they work

22:53 also there's dealing with the fact that clojure doesn't have mutability, so i have to use refs

22:54 thearthur: whats clojure for (flatten [[123][123]] ) --> ( 1 2 3 1 2 3)?

22:55 cooldude`: thearthur: my first guess is it's write it yourself

22:55 i don't think it's builtin

22:58 briancarper: seq-utils in clojure-contrib has flatten.

Logging service provided by n01se.net