3:38 knobo: I have some problems starting clojure. Is there a paste-bin I can use?
3:39 I start clojure like this: java -cp clojure.jar clojure.lang.Repl
3:39 H4ns: lisppaste8: url
3:39 knobo: And I get lot's of error messages. It starts with Exception in thread "main" java.lang.ExceptionInInitializerError
3:42 knobo: $JAVA_HOME is /usr/lib/jvm/java-6-sun-1.6.0.07/
3:43 I don't know anything about Java. Maybe I shood learn java before clojure?
3:43 Cark: i don't know anything about java either ....but it's manageable it seems
3:44 H4ns: are you starting java in the directory that clojure.jar is in?
3:44 knobo: yes
3:44 ls -l clojure.jar gives -rw-r--r-- 1 knobo knobo 498538 2008-11-08 09:32 clojure.jar
3:45 H4ns: did you compile clojure yourself?
3:45 knobo: yes, at 09:32
3:45 H4ns: what java version do you use?
3:46 knobo: haha! I did not know... java version "1.5.0" gij (GNU libgcj) version 4.2.4 (Ubuntu 4.2.4-1ubuntu3)
3:47 H4ns: erm
3:47 my guess is that you need sun java
3:47 knobo: Maybe better use sun.
3:48 H4ns: also, you will need to learn java to some extent in order to use clojure.
3:48 Cark: learn to use javadoc and you're all set imho
3:50 knobo: Do I nead to do some kind of "make clean"?
3:50 I also don't know ant
3:51 H4ns: you can remove all .class files
3:52 knobo: Hurra!
3:52 I made it :)
3:52 Cark: bravo !
3:54 knobo: I can see. I need too learn swing, and other APIs
3:55 Cark: i would recommend learning MigLayout along with swing
3:56 knobo: Can I load .jar files dynamicly after cojure has started?
3:56 hmm. well. I'll start by reading some docs.
3:57 Cark: knobo : i have a directory in the classpath with all the jar files i want to use, then just (import) them
3:58 knobo: So (import "MigLayout") should do it then.
3:59 Cark: let me copy past a namespace declaration
4:04 knobo: thanx
4:09 Is the slime patch maintained?
4:11 Cark: i don't know
4:24 knobo: How about using eclipse. Is that what people is doing?
4:25 I would like to know some best pratises
4:30 Cark: i'm using slime
4:31 i hear there's a netbean add-on too
4:31 though i would think that emacs is best suited for sexpr based languages
4:44 Cark: yep that's a problem ...
4:45 there's the wiki-book with a few examples
4:45 knobo: Why is it a problem. A wiki would solve that (almost).
4:46 Cark: well clojure is still pretty much a moving target
4:47 examples should show up in the doc strings, that would be perfect, commiters could update it in place
4:48 they're talking about making a test suite too, that would be even better !
4:49 knobo: Is clojure written in clojure?
4:50 hmm, no it's not..
4:50 Cark: nope ...much is done in boot.clj, but the basis is java
4:55 knobo: boot.clj is mostly understandable :)
4:56 Cark: it's a good reference
4:56 when you don't know how to use something
4:56 knobo: It solves a lot of the missing examples
6:48 Lau_of_DK: Good afternoon guys
6:49 Cark: hello lau_of_dk
6:57 Lau_of_DK: Anybody here got some interesting projects on Sourceforge (Clojure ofc) ?
7:17 kib2_away: hello, I wanted to know how to add a .jar to my classpath
7:18 Lau_of_DK: java -cp /path/to/your.jar:/path/to/clojure.jar clojure.lang.**
7:18 rhickey_: djkthx: still here?
7:19 kib2_away: Lau_of_DK: thanks !
7:19 Lau_of_DK: np :)
7:19 Unless your on Windows kib2_away ?
7:19 kib2_away: Lau_of_DK: yes, I'm on windows
7:19 why ?
7:19 Lau_of_DK: Then I think its java -cp "c:\jar1.jar;c:\clojure.jar" instead
7:20 The syntax is a little different
7:20 kib2_away: ok, " are there to handle spaces I think
7:20 like "Documents and Settings/..."
7:20 Cark: most important is the : which becomes a ;
7:21 Lau_of_DK: ok
7:21 kib2_away: I've tried inside my code to use (add-classpath "file://core.jar") but it fails under windows. Do i miss something ?
7:22 maybe my classpath is not well configured
7:22 philed: I'm hoping to use Clojure for my next project, since it ticks most of the boxes I want for the purpose. One thing I'm concerned about is whether there currently is or will be a means to do the equivalent of reflecting into packages and the symbol table as in CL. Any ideas?
7:24 Cark: i'm calling clojure with java -cp c:\path\to\libs\*;c:\clojure\clojure.jar clojure.lang.Repl
7:24 then i only need to (require com.some.lib)
7:24 rhickey_: philed: look at: (find-doc "ns-")
7:25 kib2_away: Cark: nice tip, thanks.
7:25 Cark: err not require but import !
7:25 kib2_away: Cark: import or use ?
7:26 Cark: import for java stuff
7:26 philed: Unfortunately, I don't have clojure installed on my home machine at the moment. But I'm thinking more like "do-symbols" and "find-symbol" and "find-package" and so forth.
7:28 philed: Very nice. That should be all I need.
7:29 It would be good to get this hooked up to SLIME so we can get some auto-complete working.
7:29 Lau_of_DK: :)
7:30 I think we need to review the wiki's recommendations on setting up slime, for every 1 person who gets it working there seems to be 10 who cannot
7:32 philed: It took me a while. I can't remember what the problem was. But I take it I have it set up correctly: there is no tab-completion available at the REPL, or any information about function arguments in the minibuffer as you type?
7:33 kib2_away: philed: C-c M-i does not do completion in Slime ?
7:34 Cark: philed : i have both
7:34 philed: Ah okay. Something's wrong with my setup then.
7:34 Chousuke: I set up tab completion manually
7:34 but the minibuffer info should be there.
7:35 philed: Yes, I've read a few articles about doing tab-completion yourself, by loading in a database of function definitions and so forth. But I want this done automatically, with updates every time I write a new function.
7:35 Chousuke: no I mean I set up tab completion separately from slime :)
7:35 Cark: swank-clojure provides this, it should work out of the box
7:35 Chousuke: it does update automatically.
7:35 philed: Okay, then I definitely have done something wrong.
7:54 Okay, so does the clojure swank server use the java reflection API to do all the tab-completions and other such stuff?
7:54 Cark: nope
7:55 philed: Any idea how it works then?
7:55 Cark: it does completion for the clojure stuff only
7:56 philed: Okay, so does it work in any way like slime for CL?
7:57 Cark: i don't know ... i'm a lispworks user.
7:59 you can check this in swank-clojure\swank\commands\basic\
7:59 i think adding the java reflection completion would be trivial
8:00 philed: Ack! I don't know what I'm talking about then. I read "the read table is currently not accessible to user programs" on the website and stupidly confused "read table" with "symbol table".
8:00 I had thought Clojure had no support for the equivalent of first-class packages, but it obviously does (and damn well should!)
8:01 Still, surely swank could be extended to use both the ns API and Java reflection?
8:01 Cark: has to because of the lisp1 thing
8:01 philed: Why would lisp1 force it to?
8:02 Cark: because of name clashes
8:03 can you imagine a single namespace a la emacs
8:03 that's ugly
8:03 philed: No I don't mean that. I specifically mean *first-class* packages. That is, packages and symbols that are first-class objects.
8:03 So you can do things like enumerate the symbols interned in a package.
8:04 Cark: you know what, i never understood the meaning of "first class" =P
8:04 rhickey_: philed: Clojure's namespaces are first class but Java's packages are not
8:04 philed: I'm not sure I could give a formal definition. I would say anything which can be bound to a variable is a first-class object.
8:04 rhickey_: but I do think IDEs/Slime could do Java completion too
8:05 there are some context hints (like the presence of . ) that can help
8:05 Lau_of_DK: rhickey_, would you mind setting that up and then updating the wiki accordingly? :)
8:05 rhickey_: but being dynamically typed, a lot of the hooks used by Java IDEs won't work
8:06 philed: rhicker: That sucks. I don't really know much Java, but then, since I'm not going to be writing much Java code, it should be possible to just put lots of metadata around existing java functions so we can get autocompletion and documentation via "find-doc". Unless this has already been done.
8:06 Chouser: nono, that's not rhickey_'s job
8:06 let him get AOT and io streams working. :-)
8:07 Lau_of_DK: I knew it was a long shot :) But they dont call me 'The Delagator" for nothing. No I actually already asked Chousuke to review the wiki, because he seems to have a well-working slime-setup
8:08 rhickey_: Chouser: It looks like cgrand is ahead of me on the io enumerators, so I hope he runs with that, then we can get it done in parallel - trying to get a dialog with him going on the group about it so everyone can follow along
8:08 philed: rhickey: By the way, though I haven't started coding in it yet, I have extremely high hopes for Clojure. The design philosophy matches up pretty much precisely with what I want from a language.
8:08 Great work!
8:08 rhickey_: Chouser: simpler doseq looks nice, I have 2 nits
8:08 philed: thanks!
8:08 Chouser: rhickey_: ok, go for it.
8:08 rhickey_: Chouser: will paste momentarily
8:09 Chouser: I got far enough in implementing that paper's io ideas, that I'm now pretty excited to see it implemented.
8:10 rhickey_: Chouser: yes, will be great addition
8:10 Lau_of_DK: rhickey_, I know this is probably also a long shot, but all these talks your doing around the US, is there any chance you'll have an oppotunity to do any such thing in Europe, preferably Scandinavia, preferably Denmark? :)
8:10 Chouser: Unless I'm missing something it won't be hard to *do*, it's more a matter of doing it well.
8:11 rhickey_: Chouser: yes, lots of little details, EOF, done protocol, timeouts etc
8:11 philed: rhickey_: Are Clojure namespaces hierarchical?
8:11 Chouser: philed: nope
8:11 rhickey_: Like most of Clojure, I'd like it to be part of a unified model, in this case making sure it encompasses queues well
8:12 Chouser: philed: but it's convention to use . to separate parts of the namespace name
8:12 philed: when used with "use" and "require" the name parts are mapped to directory names on disk, just like java packages.
8:13 Chouser: apply assoc is good
8:13 philed: Any explanation for why? I've done things in CL to get something like hierarchical packages, extending the existing hacks in CMUCL. It's nice to be able to use relative namespace names.
8:14 Lau_of_DK: rhickey_, I know this is probably also a long shot, but all these talks your doing around the US, is there any chance you'll have an oppotunity to do any such thing in Europe, preferably Scandinavia, preferably Denmark? :)
8:14 Chouser: but I don't think I can use destructuring at that point to boot.clj (I tried to at first)
8:14 rhickey_: Chouser: ah!, didn't consider that
8:14 Chouser: so apply emit was my hack attempt to use & in the fn instead
8:15 rhickey_: generally, if you always apply a fn, the sig is wrong
8:15 Chouser: I had to move partition up too, but that seems to be ok.
8:15 rhickey_: apply is fine then
8:16 I'll try your patch today if it's ready - might as well break everything at once :)
8:16 Chouser: Maybe a comment to warn people reading boot.clj looking for examples of how code should look.
8:17 rhickey_: Chouser: yeah, I'd love to just go through it and change all the Java interop to the latest conventions too
8:17 Chouser: heh, ok! You want a fresh patch against 1089?
8:17 rhickey_: but there will always be some trickiness to the bootstrap order
8:17 Chouser: yeah
8:18 rhickey_: Chouser: fresh patch welcome
8:18 Chouser: ok. no need for extra exception throwing as mentioned in the groupthread?
8:18 for "too many bindings"?
8:19 rhickey_: Lau_of_DK: no plans for Europe yet - please send plane tix :)
8:20 philed: rhickey: Maybe I could persuade some of the Foundations of Computer Science people here in Edinburgh to get you over for a talk. Philip Wadler likes Lisps.
8:20 rhickey_: Chouser: no, let's keep it simple, I don;t think people will be inclined to try multiple bindings in if-let
8:21 philed: um, Wadler likes to beat up on Lisps :)
8:21 Lau_of_DK: rhickey_, Im sure air-fare wont be a problem, but if any such practicality is preventing you, feel free to let me know, I'll help resolve it
8:22 philed: rhickey: He does? He's got a copy of the "God codes in Lisp" poem on his blog, so I thought he would probably be into them. But then, being a Haskell guy, he probably hates dynamically typed languages. Haven't chatted with him about Lisp, actually.
8:22 rhickey_: philed: those folks are way into type systems, so Clojure is rather primitive from that point of view
8:23 philed: He gave a talk at a Lisp conf to the effect of - God codes in a strongly typed lambda calculus
8:23 philed: rhickey: Yep. I like type-systems as well from an intellectual point of view, and I think what Ocaml does is pretty amazing (static duck typing). I've also seen some cool tricks with the type systems, but they seem as obscene as template metaprogramming in C++ sometimes.
8:28 arbscht_: Lau_of_DK: while you're at it, sponsor him a trip to new zealand too! :)
8:30 Chouser: and Indiana. :-P
8:33 philed: So going back to hierarchical namespaces: the only behaviour I like (which you can hack into CL) is to have it so that all symbols in a namespace foo are automatically interned in the namespace foo.bar, and having it so that, while in the namespace foo, the namespace bar can be referred to with a relative namespace name, perhaps just "bar". Depending on how the reader works, you can always add this behaviour to CL. Is it p
8:33 ossible in Clojure, or there already?
8:36 Hope this question isn't impertinent by the way. It hasn't been discussed to death already on newsgroups?
8:46 rhickey_: philed: I want to hold off on that until I see a need - with aliases, I don't see it
8:46 complexity/utility ratio is not good
8:49 philed: Would it be possible (for me) to write it as a library on top of Clojure? In CL, all you need to do is rewrite find-symbol and add a macro to define nested packages. It just requires that the reader looks up symbol definitions by using a function like "find-symbol" which can be rebound to a user-defined function.
8:49 Of course, that latter issue is not guaranteed by the CL specification.
8:51 rhickey_: philed: as evidenced elsewhere, I'm not inclined towards language customization outside of macros, esp. reader customization, as such customizations can't be combined
8:57 philed: That's fair. It opens the door to abuse. I think getting hierarchical packages in CL was justified though, since I feel there is a fair amount to be gained from them. In CMUCL, they are available out of the box.
8:57 But again, as a reader customisation.
8:58 rhickey_: Java and C# have much larger libraries and flat namespaces have been sufficient there, IMO
8:59 again, it's not that they are bad, just the complexity/utility ratio
9:01 philed: But those languages rely on OO for much of their modularity, and their model of OO means that classes *are* effectively namespaces, and are frequently nested (right). With generic functions, you don't have this, and besides, aren't you putting much less emphasis on OO with Clojure?
9:04 Chousuke: deep nesting gets confusing pretty quickly :/
9:04 rhickey_: philed: yes, classes are namespaces, no, not too frequently nested, yes, Clojure is not very OO. That said, a one-line alias or :as at the top of a file le's you get a short name for anything vs everyone (incl. tools) having to understand hierarchical namespaces. It's simply a tradeoff
9:06 philed: rhickey_: Okay, cool. I'll trust your experience on this one and try hacking with flat namespaces. There's always a chance my early exposure to C++ has clouded my judgement on this matter.
9:07 Chousuke: Right, there's be diminishing returns involved. And I have noticed this with my own code, even with only three levels of nesting.
9:09 Chousuke: on thursday I was watching a presentation about distributed systems on .NET, and the guy did a code demo. Everyone (including the speaker himself) laughed a bit when he read aloud code that accessed a property that was nested at least 5 levels :P
9:10 philed: Chousuke: Java and C# have the whole "kingdom of nouns" thing going on which just compounds the problem.
9:24 Chouser: Yegge's got reach, doesn't he. If only Google would let him use Clojure.
9:28 drewr: I don't see why he couldn't. They already have a huge JVM infrastructure.
9:28 Should be easier than the Ruby battle he's been fighting.
9:29 he's only allowed to do his Rhino experiments because it's js and java.
9:30 Chousuke: I took a look at the wiki slime set up guide and changed it a bit to match how my setup is done.
9:30 I don't know if it works for others but it works for me :/
9:30 mostly it was the same though.
9:30 drewr: Chouser: He's said that limitation is based on deployment. Clojure would require little infrastructure change if any.
9:31 Chousuke: I also added a tab completion trick I found on the internet somewhere that I use
9:35 drewr: I get the impression he'd prefer a lisp if it was practical. I think he only puts up with JS because it's the most lispy of the mainstream languages.
9:39 hola wilkes
9:40 kotarak: drewr: (-> obj .getAThing .makeMore .actions) vs. obj.getAThing().makeMore().actions()... 2 vs. 6, aha, so Java is the actual Lisp...
9:41 wilkes: howdy drewr
9:42 drewr: I made a bit of headway yesterday on the pivotal-tracker client
9:42 drewr: kotarak: :-)
9:43 wilkes: accidently created a DSL
9:43 drewr: I see that.
9:46 philed: kotarak: Still, there is something to be said in the fact that I couldn't write Lisp code without paren matching switched on, while I can write procedural code with C-like syntax without any difficulty.. That said, when you have paren-matching, I have not found Lisp syntax any more of a pain than any other language, and the benefits of code-as-data and syntactic macros make Lisp syntax far superior. Now that mainstream lan
9:46 guages such as C# are taking syntactic abstraction seriously, I think it will be easier to convince programmers of this, especially when working with C# expression objects (and Ocaml expression objects) is so much more painful.
10:13 rhickey_: Chouser: bindings patch applied - rev 1090. Thanks, that's a significant contribution!
10:14 Chouser: great, thanks.
10:14 i assumed there were a dozen or more such macros, so it's not as significant a contribution as I assumed it would be. :-)
10:15 rhickey_: still a lot of work - I appreciate it
10:17 Chouser: you're quite welcome. I'm all about breaking other people's code.
10:18 rhickey_: nice
10:18 aargh, forgot to give you blame, er, credit in the checkin comment
10:20 Chouser: :-) no worries.
10:20 rhickey_: I guess there's a lot todo to bring contrib up to speed too
10:21 Chousuke: doseq etc. are like let now?
10:21 rhickey_: The next phase of AOT is a big one for contrib - moves directories around
10:22 Chousuke: yes, per: http://
10:23 also for AOT the mappings will now be from my.company.lib ns to class lib in my.company package Java-wise
10:23 this won't affect ns/require/use et al, but will lift everything up a directory
10:24 but biggest change is that clojure ns should really be at least one nested, lest it have no Java package, e.g. clojure.core
10:25 thinking about some standard aliases - core/set/xml/zip etc
10:27 Chouser: bah, I forgot to add the comment for (apply emit binds)
10:27 rhickey_: Chouser: when people start noticing that we'll be in good shape
10:28 Chouser: heh
10:32 djkthx: rhickey_: here now
10:33 rhickey_: djkthx: you were doing sieve?
10:34 djkthx: yeah
10:34 djkthx: yeah, why is it faster?
10:35 rhickey_: djkthx: because it uses primitives
10:35 djkthx: ah, gotcha
10:35 thanks :)
10:35 rhickey_: sure
10:36 Chouser: I was noticing that since doseq uses loop/recur, it could benefit from primitives, except there's no way to specify them.
10:37 would the benefit be to little just because it's always pulling from seqs?
10:37 rhickey_: Chouser: doseq uses numbers?
10:38 or if the seq contents are numbers?
10:38 Chouser: if the seq contents are numbers. range, primes, fibs, etc.
10:39 rhickey_: yeah, time will probably be dominated by seqs
10:40 Chouser: ok.
10:41 rhickey_: numbers will be boxed in seqs anyway, unbox is no big deal
10:43 Chouser: You might get primitive logic in :when and :while, but I can see it might not help much.
10:44 rhickey_: once you are at that point you're looking at amap/areduce anyway
10:45 Chouser: pity. :-)
10:45 rhickey_: tagged numbers needed to do better with Object-based interfaces
11:10 mibu: I have a question regarding recursive calls.
11:10 What exactly is the semantics of recur?
11:11 Chouser: recur is like a call to the immediately containing function or loop
11:11 except it doesn't consume a stack frame
11:13 mibu: Well in the paste above, line-seq recursively call line-seq. I assume it's possible because defn creates a var of line-seq instead of a let binding. But shouldn't that have worked with recur instead of line-seq? (It doesn't)
11:14 kotarak: The function returns, before the "recursive" call happens because of the lazy-cons
11:16 Chouser: yeah, lazy-cons is the key. Neither of it arguments is evaluated immediately; they're both deferred until needed.
11:16 mibu: ok. so how do I create recursive references when not using defn? for instance in a let binding clause: (let [lines (something) seqqer (fn [seq] (lazy-cons (re-seq #"\\w+" (first lines)) (seqqer (rest lines))))] (seqqer lines))
11:17 seqqer is not recognized in the fn def.
11:17 kotarak: seqqer (fn seqqer [seq] ...)
11:17 (where seq is a bad local variable, because it shadows the function seq)
11:18 mibu: oh! thanks.
11:18 isn't it a little redundant?
11:19 kotarak: I almost never need it.
11:19 but letrec is on the TODO list
11:21 mibu: why use a different symbol for a recursive let?
11:35 AWizzArd: Moin
11:43 mibu: Is there a last-value-evaluated var in the REPL (like '*' in CL)?
11:43 rhickey_: mibu: *1 *2 *3
11:43 kotarak: *1 *2 *3 *e (<- last one is exception)
11:44 mibu: thanks.
11:45 ah, that's not in the latest release (...0916), right?
11:45 AWizzArd: try the svn
11:45 mibu: I will.
11:47 Chouser: don't use the *latest* svn, though, unless you're feeling adventurous.
11:47 rhickey_: mibu: the last 2 checkins contained significant changes - try rev 1088 for the smoothest ride
11:48 anyone have any issues with clojure ns being renamed clojure.core ? (aside from the breakage)
11:48 mibu: rhickey: thanks. I will.
11:49 kotarak: rhickey_: why not clojure.lang? Would match the java side. (Although that might be a problem)...
11:50 rhickey_: kotarak: I'd rather avoid mixing the generated classes from the two sources
11:50 also would cause a class and a package to be called clojure.lang
11:51 most of what is in there (currently boot.clj) is core library, not language syntax
11:51 so seems easiest to have a different name
11:52 kotarak: just an idea.. Separating the underlyings from the core librarary running on the former is a good argument
12:07 mibu: Is there an active issue tracker somewhere? (todo list, feature requests, known bugs, release schedule, and the like.)
12:08 mibu: thanks
12:09 kotarak: mibu: feature request are discussed on the Clojure list of google groups
12:09 mibu: bugs are dropped here and are immediately fixed by Rich. :)
12:09 mibu: :-)
12:09 kotarak: (of course they can also go to the Clojure list)
12:12 mibu: the group is good to keep track of what's happening right now, but for newcomers (I am one) it's hard to see what was already discussed in the past without reading everything. right now, I'm trying to wrap my head around what's the current status of things and where it's going.
12:14 rhickey_: mibu: I hope to move to a tracker soon, the todo represents those things that made it onto the agenda
12:15 scary - just got rid of clojure namespace
12:15 (and Clojure still works)
12:16 kotarak: Clojure finally transcedented to a higher being and doesn't need such profane things like a namespace anymore.
12:17 mibu: rhickey, is the project right now still rapidly changing or is it converging to something stable enough for production code?
12:17 (I'm good with rapidly changing. I just need to know)
12:18 AWizzArd: I feel its rapidly changing into something stable for production code :-)
12:18 mibu: :-)
12:18 rhickey_: mibu: there are very few breaking changes. A few have built up and I am putting them in now in prep for a 1.0 release. While there is a lot of dev activity, it's mostly enhancements/additions
12:19 kotarak: I had relatively few troubles lately. The biggest fluctuations in my code were during the require/use/ns transitions.
12:19 AWizzArd: As soon we can compile everything into .class files and deliver apps the biggest hurdle for some companies is gone.
12:19 rhickey_: It only seems rapidly changing for those that want to try the latest toys
12:19 AWizzArd: ...and deliver apps without delivering code...
12:20 rhickey_: AWizzArd: coming soon
12:20 AWizzArd: yes, and I am beginning already translations
12:21 mibu: I think it makes sense to begin *now* to work on your products. If it is something that needs several months anyway then everything will be in place as soon you are done.
12:22 mibu: I'm all good with changing tech (what else am I doing here?), but my colleague are not. Changing tech means it's improving and not yet bound by compatibility issues and standards (like CL).
12:23 AWizzArd: we are not forced to use newer versions.. one could simply stick to one of them and nothing will change
12:24 rhickey_: AWizzArd: true, the only caveat being that right now bug fixes and new features come together
12:25 mibu: awizz: yeah, but when things change fast you want all the latest cool toys at your possesion. otherwise you feel like using tape recorders in a world of Ipods.
12:26 AWizzArd: Yes, that's right. Anyway, Clojure was done mostly right, and I think there won't be dramatic changes that would force us into full rewrites. But standing still like CL mostly is, is also not a good option.
12:30 mibu: I think CL also got the basics right, the only cardinal problem was the libs. Think about CL with a Java like library and it's pretty sweet. Of course, I welcome the much improved changes in clojure.
12:32 AWizzArd: CL still challenges us to not do what it offers: like imperative programming. One of the reasons that CL has not enough libs is that one needs big efforts to make them compatible.
12:32 Java allows more or less only one way to do it. So everyone has to do it the same way, and often ends up with libs that can be shared and used with/by others.
12:36 mibu: now that I think of it, every single successful language in the last years became successful thanks to a batteries included philosophy--large useful well-documented library. It worked for perl, java, python, and I assert it's also true in relative terms to C.
12:39 AWizzArd: Sure, a large library is the most important factor for productivity. The biggest factor for productivity is code reuse. If systam A already has a lib to do some stuff then making just a few calls is simply the easist thing to do. Clojure is prepared here, as Java offers the more or less biggest code base.
12:43 mibu: now that the library factor is covered, I think concurrency is the biggest issue, and immutability pretty much untangles that. Now the last two factors left is documentation and a following.
13:03 1088 rev broke something with regexes. Is it just me?
13:03 (moved from the 0916 release to 1088 svn)
13:05 basically, \ doesn't need to be escaped
13:06 mibu: Ah, thanks. That did it.
13:10 People working with code from Eric Rochester's blog will have problems. http://
13:12 Google's captchas are getting ridiculous. I tried living a note about the change in the above link, but couldn't decipher the captcha...
13:12 * mibu is coming to a realization he is not human.
13:13 mibu: *leaving
13:54 AWizzArd: rhickey_: http://
13:58 rhickey_: a little typo in "defonce". It should be "if" instead of "iff" I guess.
13:59 rhickey_: AWizzArd: page fixed - thanks
14:00 AWizzArd: iff == if and only if
14:00 AWizzArd: I see
14:00 rhickey_: in (defn concat ... ) there is a (if (seq x) ..) was this supposed to be (seq x) or should it be (seq? x) instead?
14:01 (in the now newly named core.clj)
14:01 rhickey_: AWizzArd: wow, you are bleeding edge
14:02 it is correct as is, testing a seq for non-nil idiom == is there more?, seq call only needed because it might not yet be one (i.e. an empty vector)
14:18 Jedi_Stannis: Hi, I'm trying to access javax.swing.GroupLayout.Alignment.TRAILING and the other Alignment constants, but can't fgure out the syntax for it in clojure
14:20 Chouser: javax.swing.GroupLayout$Alignment/TRAILING
14:20 $ for a nested class, / to access a static member of that class
14:22 Jedi_Stannis: is that document anywhere? I didn't see it anywhere on the website, I knew about / just not $
14:24 Jedi_Stannis: oo, its kinda hidden in the . special form, I was looking for something in bold
14:25 thanks though
14:26 I have GroupLayout imported, but still need to fully qualify for $Alignment to work, is that expected?
14:26 rhickey_: GroupLayout and GroupLayout$Alignment are 2 different classes
14:28 you can import it too (import '(javax.swing GroupLayout GroupLayout$Alignment))
14:28 Jedi_Stannis: got it
15:38 AWizzArd: rhickey_: motivated by the google groups kotarak and I were discussing about why do is a special form and not simply implemented as a function: (defn do [& body])
15:42 Chousuke: hmmh
15:42 rhickey_: while everything can be looked at as an expression in CLojure, some things are not actually expressions and I have to fake it, like void methods
15:43 those are exactly the kinds of things you'll have in do bodies, in which case there is no realized expression value produced
15:43 if they were fn args I'd have to produce them
15:43 plus there's some overhead to & body and arg packing
15:44 AWizzArd: I see, thanks
16:28 sohail: do you guys use ns for multi-file projects?
16:29 Chouser: depends on why I'm using more than one file
16:29 sohail: Chouser, interesting statement. for me, I'm writing an app that is getting too big for one file now :-)
16:31 Chouser: clojure.contrib.lazy-xml has two files. The secondary file depends on a 3rdparty lib, so the main file uses load in a try block to use the 3rdparty lib if it's there or to fail gracefully if it's not
16:31 sohail: where is clojure.contrib?
16:32 Chouser: clojure.contrib.zip-filter has a set of features just for xml that not all users will need, so it's in a separate namespace, clojure.contrib.zip-filter.xml
16:33 sohail: Chouser, ok none of these sound like: "This file is too damn big."
16:33 Chouser: https://
16:34 sohail: yeah, I haven't run into that problem yet.
16:34 sohail: ok so say you had, would you be using ns for that?
16:34 Chouser: I guess it depends on your definition of "damn", or perhaps "big". Have you seen boot.clj?
16:34 sohail: I have
16:34 Chouser: >3600 LOC -- you've got more than that?
16:35 sohail: no
16:35 that's pretty damn big though
16:35 besides, I'm putting a lot of stuff together that really shouldn't be... mixing GUI and non-GUI things
16:35 Chouser: I guess if there are natural divisions, esp. reusable chunks, I might break those into namespaces.
16:36 otherwise I'd tend to keep it in one big file.
16:36 I'd rather have a big file, then have 2 small ones and not be sure where exactly I put a particular function.
16:37 gotta go
16:37 AWizzArd: I sometimes can't decide when something should go into another file. And even in one file I am sometimes splitting functions into 2-3 parts, although these are then used only once, for the main function.
16:37 sohail: where's the ant colony simulation code
16:38 that's gotta be kinda big atleast
16:38 AWizzArd: sohail: check GG or the vid
16:39 sohail: AWizzArd, what is GG?
16:39 and I saw the vid, but it was not obvious how the code was structured
16:39 AWizzArd: google groups
16:39 sohail: the code is attached to the vid, there is some link below the vid itself
16:40 sohail: lol, that's tiny
16:42 AWizzArd: 150 loc for the non-gui stuff, without comments and whitespace-only lines
17:15 knobo: Is it possible to write java objects in clojure?
17:15 delete that line
17:15 Is it possible to define java classes
17:15 kotarak: Yes. With gen-class
17:15 (doc gen-class) in the Repl gives more information
17:16 AWizzArd: note it is possible though that gen-class will get replaced by something
17:17 knobo: So I could use clojure when working with tomcat for exaxmple
17:17 AWizzArd: absolutely
17:17 everywhere, where you can also use Java
17:17 knobo: For mobile-phone applications
17:18 AWizzArd: yes
17:18 and soon this will be simpler
17:19 knobo: I feel I am starting to become a member of the society again :)
17:19 AWizzArd: the mobile phone stuff will probably be more available in 2009 as I understand it
17:19 knobo: I have been an outsider, programming in common-lisp
17:20 AWizzArd: I also come from CL
17:20 knobo: I actualy have a paid job programming CL :)
17:20 for now....
17:20 AWizzArd: same with me :-)
17:21 Clojure will offer most Lispers a way to get a job in which they can do Lisp
17:22 knobo: even openoffice.org
17:23 danlarkin: is there a class that all clojure collections implement?
17:23 AWizzArd: what do you mean?
17:23 danlarkin: you mean class or interface?
17:23 rhickey_: danlarkin: clojure.lang.IPersistentCollection
17:24 danlarkin: rhickey_: thanks :)
17:25 rhickey_: chart courtesy of Chouser
17:33 AWizzArd: rhickey_: is it easy to use the Clojure datastructures in Java too?
17:35 rhickey_: AWizzArd: sure, there are interfaces for everything. Their functional style is not idiomatic Java, though
17:36 AWizzArd: But does one need to do a lot of casting? I don't understand the static type system of Java not well enough. I think Clojures DS all work on Object and could need casting
17:37 Moin Lau
17:37 Lau_of_DK: Ola AWizzArd
17:38 rhickey_: AWizzArd: yes, they are all Object based, just like pre-generics Java collections
18:00 sohail: hmm.. anyone getting this with latest clojure: Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class clojure.lang.RT at clojure.lang.Script.main(Script.java:71)
18:00 Lau_of_DK: no
18:00 sohail: seems clojure.lang.Repl has disappeared for me too... maybe I need to rebuild it again
18:01 Lau_of_DK: distclean
18:01 sohail: Target "distclean" does not exist in the project "clojure".
18:02 * sohail is using ant
18:02 rhickey_: ant clean ?
18:03 sohail: tried that too
18:04 Lau_of_DK: hehe
18:04 I know, I just meant, clean up the old before you start on the new
18:06 sohail: crap client on phone
18:08 rhickey_: sohail: stick with rev 1088, lots of changes in last few checkins
18:09 sohail: rhickey_, ok thanks
18:09 ok this version works
18:10 kotarak: sohail: with the latest check-in clojure is gone.
18:10 sohail: clojure is dead, long live clojure.core
18:10 sohail: kotarak, oh noes
18:10 ah, I see
18:10 so clojure.core.Repl?
18:10 kotarak: sohail: just kidding. Rework of the clojure namespace.
18:11 I think Repl should still be in clojure.lang
18:11 sohail: 's not!
18:11 Lau_of_DK: For an immutable language, the namespace-stuff sure mutates alot
18:12 sohail: haha
18:12 Chousuke: heh
18:12 better mutate now than be stuck with a suboptimal solution forever
18:13 duck1123: that's okay, yesterday I did a pull of one of the emacs libs I use. The maintainer switched hosters, and basically told everyone by deleting all the files with the commit message "it's gone"
18:13 Lau_of_DK: haha
18:14 Chousuke: well that'd at least encourage people to investigate what has happened.
18:14 though the commit message could've been better...
18:14 duck1123: and Lau_of_DK, that's one of the benefits of git. even had I not found where it went, I would've still been able to back it up a revision
18:15 Lau_of_DK: Same with SVN though, right duck1123 ?
18:15 duck1123: what if he shut down the server between the time I pulled and realived what happened
18:16 rare risk, but still...
18:17 Lau_of_DK: Sure, and if you combine that with a sudden Earth/Moon collision, hitting directly on top of your broad band connection, you might also experience great packet-loss, but as you said.. rare risk
18:18 duck1123: I don't need the moon to hit the earth, I have DSL
18:18 Chousuke: well with GIT you could rehost the old repository easily.
18:18 with SVN all the history would be gone,
18:18 Lau_of_DK: oh I see
18:19 Chousuke: the big thing with git is that any clone of a repository is equal with its origin
18:20 Lau_of_DK: same with SVN though, right?
18:20 Chousuke: no
18:20 with SVN, your checkout is still dependent on the repository you checked out
18:21 you can't for example have other people check out your version of the repo
18:21 which, with git, is trivial :)
18:21 Lau_of_DK: I cant have them checkout my version? What can they checkout then ?
18:22 Chousuke: the repository.
18:22 Lau_of_DK: oh I see, so you mean that Git checksout all the versions when you co ?
18:22 Chousuke: well, kind of.
18:22 it *clones* the entire repository
18:23 so if you have repository A and clone it as A', then as long as no modifications are made on either repo, they contain the same data
18:24 including history
18:24 Lau_of_DK: k, but thats still the same as SVN though, just excl. history
18:25 arohner: Lau_of_DK: no. In SVN, there is a master/slave relationship. When you check out, you get a copy of the current revision. Doing anything requires talking to the repo that you checked out from.
18:25 Chousuke: but with git, you could make modifications and someone could clone your A'.
18:25 duck1123: with svn, if you can't reach the repository (due to lunar disaster) you can't make any commits
18:26 Chousuke: without even knowing that A existed
18:26 Lau_of_DK: oh I see, so theres more a bittorrent approach to Git
18:26 Theres no central hosting for Git is there, people use their own servers primarily ?
18:26 Chousuke: there's no "master" in git, other than by policy.
18:27 kotarak: Lau_of_DK: there's github
18:27 duck1123: so my github repository is just a copy of what I have here at home
18:27 Chousuke: you can decide that there's a "central" server, but technically it's just another git repo
18:28 Fanda: hello!
18:28 kotarak: Which basically applies to all newer systems: hg, bzr, darcs...
18:28 arohner: Fanda: hi
18:28 Fanda: just wanted to ask, what sources have you used for learning how to write macros
18:28 i like clojure very much, but macros give me hard time
18:28 arohner: Fanda: some people have recommended On Lisp
18:29 sohail: hey Lau_of_DK, in your qt api thingy, how are you handling designer stuff?
18:29 duck1123: and mr rules them all
18:29 Fanda: i am looking into: Practical Common Lisp
18:29 Lau_of_DK: Fanda, theres actually a section on the Clojure Wiki about that now
18:29 arohner: Fanda: that's another good option
18:29 Fanda: reading the clojure source is also good
18:29 Lau_of_DK: sohail, 2 ways: 1) For everything except Webkit, use 'designer' and import the UI, 2) Webkit: Hardcode
18:29 Anyway, thanks to everybody for your explanations on Git vs Svn
18:30 Fanda: yes, I will read all: On Lisp, PCL and wiki :-)
18:30 sohail: Lau_of_DK, so you mean you have an extra juic step?
18:30 arohner: Fanda: in the source tree, src/clj/clojure/boot.clj
18:30 Lau_of_DK: You mean when I dance, or when I code ?
18:30 sohail: Lau_of_DK, both
18:31 Lau_of_DK: sohail, haha
18:31 What do you mean by juic step ?
18:32 sohail: Lau_of_DK, because designer has the ui files, do you use juic to generate the actual code or do you use the dynamic equivalent?
18:32 I think it's forms
18:32 I haven't used forms
18:32 Lau_of_DK: oh hang on
18:32 Fanda: arohner & all: thanks for pointers about macros
18:33 Fanda: it is gonna take me a little time to learn just it... just getting impatient here :-)
18:33 Chousuke: Fanda: if you're going to read PCL, this will help as well: http://
18:33 Fanda: yes, that's true - completely forgot about it :-)
18:34 is there any other way than using macroexpand to see what's happening?
18:34 sohail: Lau_of_DK, perfect, that's what I thought
18:34 right now I'm using code
18:34 which is so ugly it's not even funny
18:34 Lau_of_DK: hehe, its swing-like ugly
18:34 arohner: Fanda: macroexpand is your best option
18:35 I'm not sure if there are other options
18:35 are you an emacs user? because slime makes it very convenient
18:35 Chousuke: Fanda: I think most important is to not get overly excited about macros though.
18:36 Fanda: usually, i just use simple editor and repl
18:36 sohail: Lau_of_DK, well I have never explored this part of the Qt framework before so I will be bugging you :-)
18:36 Fanda: I have worked with macros in the interpreted-only LISP
18:36 Lau_of_DK: sohail, bug away :)
18:36 Fanda: macroexpansion at compile time is new to me
18:37 Lau_of_DK: then you should try compilemacro at expansion time
18:37 ..but thats really advanced
18:38 Chousuke: clojure syntax-quote is a bit different from the common lisp quasiquote too. At least, I think so. I haven't yet grasped all of the macro-fu myself either.
18:38 arohner: they're fairly easy to translate between
18:38 there's a 1-1 correspondance for most things
18:38 Fanda: ok, example
18:38 a=1, b=2, c=3
18:39 Chousuke: the namespace-qualifying thing makes a difference though.
18:39 Fanda: (mac a b c) => ((a 1) (b 2) (c 3))
18:39 yes, namespaces and other symbol lookups make it hard for me
18:39 arohner: so you want the symbols to be bound to sequential integers starting at 1?
18:40 Fanda: just any symbols
18:40 and any numbers
18:42 (def a 1) (def b 2) (def c 3)
18:42 sohail: what does this syntax mean? (QIODevice$OpenMode. something)
18:42 Chousuke: sohail: inner class
18:42 sohail: I'm not fully up to snuff on my java interop syntax
18:43 Chousuke, what about the trailing dot?
18:43 Chousuke: it's "new"
18:43 that's the same as (new QIODevice$OpenMode something)
18:43 sohail: ah
18:43 * sohail prefers new today
18:51 Fanda: can i have one more question about macros?
18:51 let have: (def a 1) (def b 2) (def c 3)
18:51 (def lst '(a b c))
18:52 what expression do you write in order to evaluate symbols inside the list 'lst'?
18:52 user=> `~lst
18:52 (a b c)
18:52 user=> `(~@lst)
18:52 (a b c)
18:53 user=> (map eval lst)
18:53 (1 2 3)
18:54 danlarkin: Wow, type hints give me a 6x running time decrease
18:54 I didn't expect it to be nearly that much
19:03 verec: rev 1092 throws java.lang.ClassNotFoundException: clojure.core$eval__1 (core.clj:0)
19:03 compiledClass = RT.classForName(name);
19:03 line 3198 in Compiler.getCompiledClass
19:04 danlarkin: verec: revert to r1088 for a while
19:05 verec: Ah. OK. Thx
19:06 arohner: do type hints work in the middle of function calls?
19:06 i.e. (foo #^java.lang.String bar)?
19:08 and, on a javadoc, what does "..." mean in the type signature?
19:08 danlarkin: arohner: I don't think it works that way, only in function arg lists that I know of
19:08 Chousuke: arohner: variadic?
19:09 arohner: huh. Didn't know java supported that
19:27 oh, that was fun.
19:27 in this instance (I'm not sure about all), ... meant "array of"
19:27 and if you want an array of strings, (into-array string) is not what you want
19:27 you want (into-array [string])
19:28 otherwise you get an array of chars
20:17 AWizzArd: Is there a string-reverse? (str-reverse "123") ==> "321"
20:19 rhickey_: AWizzArd: (str (reverse "123")) ?
20:19 AWizzArd: I know how to do this without a str-reverse, I'm just curious if there is something like that.
20:19 rhickey_: no dedicated function
20:20 AWizzArd: (str (reverse "123")) ==> "(\\3 \\2 \\1)" for me
20:20 (reverse "123") ==> (\3 \2 \1)
20:20 Chouser: (apply str (reverse "123"))
20:21 AWizzArd: Chouser: yes, I am doing this so far
20:21 Chouser: you could lobby Stuart Sierra to add it to clojure.contrib.str-utils
20:21 AWizzArd: ok
20:24 How would you name it if you had to chose a name for it?
20:24 rhickey_: ick
20:25 AWizzArd: What does it stand for?
20:25 rhickey_: do we need such specialized fns?
20:25 AWizzArd: not necessarily
20:25 depending on how regular people reverse strings
20:26 but one could argue if people would expect (reverse "123") to return "321" or (\3 \2 \1)
20:27 Chouser: reverse returns a seq.
20:27 (reverse [1 2 3]) doesn't return a vector, so why should (revers "123") return a string?
20:27 AWizzArd: right
20:27 although it's probably what most people would think about it first
20:28 if reverse were a multimethod one could dispatch for the argument type
20:29 whatever, (apply str (reverse my-string)) is fair enough
20:43 scgilardi: rhickey_: I'd be happy to update the former contents of boot.clj to the lispy Java interop syntax if that would be helpful and isn't already being tackled.
20:45 rhickey_: scgilardi: at some point that would be great - but right now I've got it my hands deep in - just booted Clojure with no source - all from classfiles!!
20:45 hands deep in it
20:45 scgilardi: rhickey: ok, cool. Nice! another milestone passed.
20:46 rhickey_: boots like lightning
20:47 scgilardi: you might want to think about how lib will work when we have pre-compiled libs, some sort of try the class first, then the source
20:47 for load
20:51 scgilardi: yes, ok. maybe a new flag to force a compile or recompile as well. I haven't looked at the newest yet, is there a new routine to load a class file compiled from Clojure?
20:53 rhickey_: scgilardi: not yet, still working out loading logistics. We'll need compile, load, compile-and-load - still subject to limits for reloading of classes, i.e. reload must always be from source
20:58 scgilardi: rhickey_: is that a limitation to preserve programmer sanity or something more fundamental to how things work?
20:58 rhickey_: Java can't load a class twice into same classloader
20:58 scgilardi: does it also have no notion of unloading?
20:59 rhickey_: yes, no unloading
20:59 scgilardi: ok I understand
21:14 sohail: runonce
21:14 is it even possible with STM?
21:14 I think it isn't
21:14 so maybe Stuart shouldn't be using refs and friends for runonce
21:20 rhickey_: woo hoo!! AOT rocks!
21:20 AWizzArd: grats
21:21 rhickey_: clojure.jar with no source inside
21:21 Chouser: nice
21:21 scgilardi: and we were here when...
21:21 don't be goin' closed source on us.
21:22 rhickey_: source on the side
21:22 scgilardi: special source
21:22 rhickey_: sadly, clojure.jar crosses 1mb mark
21:23 would still fit on floppy if they existed
21:23 AWizzArd: perhaps one day there could be deployment tools, like those for CL that can strip out parts that will not be used in the app itself
21:24 Chouser: my clojure.jar is half that
21:24 rhickey_: Chouser: right, precompiling doubles it
21:24 Chouser: even without the source, huh?
21:24 rhickey_: I haven;t worked on size at all
21:25 Chouser: sure
21:25 rhickey_: including source only adds 150k
21:25 AWizzArd: but it seems to reduce loading times a little :-)
21:25 Chouser: hm. .jar's can be zipped, can't they?
21:25 anyway, shouldn't matter much.
21:26 rhickey_: reduces load times a lot - hard to measure, but it may be 5-10x reduction over Java baseline
21:26 gotta run
21:26 AWizzArd: Chouser: .jar's already are zipped
21:27 Chouser: AWizzArd: ah
21:28 scgilardi: I know the latest svn is marked interim, do not use, but I gather it's possible to use. For me, it fails with ExceptionInInitializer in Repl.java. What's the trick?
21:29 AWizzArd: n8 n8
21:38 scgilardi: sohail: could it perhaps be done with a counter instead of a boolean? Would it be possible for one of the parallel invocations to know that he was the one that accomplished the transition from 0 to 1 on a runcount and proceed with the run?
21:40 sohail: scgilardi, or just use a mutex and boolean :-)
21:40 scgilardi: from java.util.concurrent yep.
21:41 sohail: i'm sure java has some more efficient interface to pthread_once
21:42 scgilardi: sounds right. I haven't thought through all the options for updating a ref in a transaction. Everything I've done has worked with commute.
21:42 sohail: scgilardi, I think the counter wouldnt work either
21:43 scgilardi: it seems that if the update were done in a dosync before running the function, a call to ensure could allow one thread to know it was the one that made the 0 to 1 transition.
21:43 sohail: whats dosync anyway
21:44 scgilardi: in fact, that's the same as a false to true transition, so a counter isn't necessary, it's just necssary to know that the ref was false before (this thread) changed it.
21:44 sohail: well if there are no side effects then it doesnt matter really
21:45 scgilardi: dosync wraps Clojure's ref operations
21:45 it seems that runonce would only be useful when there are side effects.
21:45 sohail: yep :-)
21:46 I don't have my head quite wrapped around STM but my understanding is that each transaction occurs within a timeline, so two could occur at the same time in the same timeline
21:47 only one will succeed of course, but the effects are that it ain't runonce!
21:48 scgilardi: If only one thread will run the function and that thread will only run it once, it seems to me that it is exactly runonce.
21:48 sohail: I think it is still possible for two threads to run the function
21:48 you need the stm guy, rich to tell you it ain't so!
21:51 Jedi_Stannis: is there a way to eval in the current scope? I have a gui program that is trying to call eval on the text in a text field, but it can't find the function I have defined. the same function works fine from the repl
21:56 Chouser: (binding [*ns* (find-ns 'user)] (eval ...))
21:57 oh, maybe not
21:59 yeah, I think that's it.
21:59 Jedi_Stannis: chouser: nope, that worked
22:30 julian_morrison_: hi, folks
22:30 Chouser: hi
22:31 julian_morrison_: does anyone know how to use (with-open x y ...) in a macro? defmacro qualifies the x and then complains about letting a qualified symbol
22:32 duck1123: ~x
22:32 I've been fighting that all weekend
22:32 julian_morrison_: and to access it from inside after expansion?
22:33 supposing it's JDBC and the x will end up being the conn
22:33 duck1123: you use x at first, ~x later
22:33 julian_morrison_: can you paste an example?
22:38 duck1123: one sec
22:38 julian_morrison_: I'm trying to (defmacro connected ([& body] `(with-open conn (DriverManager/getConnection ...) ~@body))) and then (connected (.createStatement conn))
22:39 do I need to use vars and bindings?
22:39 look at with-model
22:40 julian_morrison_: Ah. Thanks, that's about perfect.
22:41 duck1123: looks like we were doing very similar things.
22:41 you were probably thinking about bindings due to clojure.contrib.sql
23:13 danlarkin: wow, 2x running time difference between passing around a hash-map of args versus each function having n number of arguments
23:14 duck1123: wow
23:14 how many args?
23:15 danlarkin: 4
23:16 duck1123: is there a fn that'll take a seq and filter out the dups?
23:16 danlarkin: I think it's all the object creation the JVM has to do, it isn't very fast at that type of thing I think
23:16 duck1123: nvm, found it
23:23 danlarkin: is there a better way to express this: (if (nil? (first coll)) 'foo (first coll))?
23:25 Chouser: (if-let x (first coll) x 'foo)
23:26 soon to be (if-let [x (first coll)] x 'foo)
23:26 ...assuming it's ok to treat "false" like "nil"
23:27 danlarkin: in this case it is indeed