#clojure log - Dec 12 2008

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

4:14 AWizzArd: Moin moin

4:17 Lau_of_DK: Hola Senior

4:25 AWizzArd: que tal?

4:57 Bracki: clojure.lang.PersistentHashMap cannot be cast to java.util.Map

4:57 So how do I get a Map from {}?

5:08 Chousuke: Bracki: are you running the release version of clojure?

5:09 Bracki: you'll have to use a more recent version

5:11 Bracki: yeah running svn this very moment

7:12 Kerris7: http://blog.rubyenrails.nl/articles/2008/12/12/calling-clojure-from-jruby

7:12 Clojure + jRuby :o

7:40 Lau_of_DK: Kerris7: Calling Clojure FROM Ruby? Thats gotta give some overhead

7:40 Kerris7: jRuby

7:41 Lau_of_DK: Same

7:42 Chousuke: well, jruby already runs on the jvm so the overhead should be minimal

7:47 Lau_of_DK: I doubt it

7:47 Ruby is grade F material

7:48 http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=all

7:51 blackdog: well to give ruby it's due it at least showed "enterprise" developers that they'd been duped by complexity for too long

7:55 as does clojure

7:58 Chousuke: Lau_of_DK: I thought you meant the overhead of combining ruby and clojure :)

7:59 if they'd just get 2.0 out the rubyists might actually save themselves

7:59 1.8 is just meh.

8:00 Lau_of_DK: I might be wrong, but to me it looks like all Ruby is released under the slogan "For noobs, by noobs", like Python

8:07 rhickey: Should be an interesting day in the blogosphere: http://tapestryjava.blogspot.com/2008/12/clojure-hundred-year-language.html

8:09 leafw: rhickey: clojure is becomming what arc was designed for. But I don't think PG cares at all.

8:12 rhickey: I don't think so either. It's quite flattering, but I'm always concerned about not overstating things for Clojure

8:13 Chouser: I think that attitude, as well as standing well clear of general language bashing, have been wise and served Clojure well.

8:14 * rhickey prepares for inevitable Clojure backlash :)

8:14 leafw: as the saying goes: be so good that, even when hated, nobody can afford to ignore you.

8:16 blackdog: i think you're well covered rhickey , as for example ruby backlash is on scalability, you i can't imagine a lot of complaints on the language itself

8:16 clojure that is

8:19 octe: what does "#" mean in clojure? i'm looking at the built-in and-macro..

8:20 rhickey: octe: # is a dispatching reader macro, whose meaning is determined by the next character, documented here: http://clojure.org/reader

8:22 octe: thanks, i was looking for a reference for the macro characters :)

8:26 thoughtpolice: apparently android's dx tool does not like the clojure.jar file :(

8:29 and i finally got the AOT compiler to work and compile my stuff against android.jar, at least.

8:30 rhickey: thoughtpolice: I only got to try it for a few minutes (dex), and saw one bytecode thing its verify didn't like (but Java's does, as Clojure bytecode does verify). Have you got a specific problem?

8:31 AWizzArd: # can also be a postfix reader macro, as shortcut for gensym.

8:37 rhickey: yesterday we discussed static typing for some moments. In that regard, do you think that it could make sense one day to have no automatic (empty) implementation for checked exceptions?

8:38 rhickey: AWizzArd: I don't understand

8:39 AWizzArd: As I understand it, in Java there are so called checked exceptions. You are not forced to put a division every time you want to use it into a try/catch block. But with checkey exceptions you have to.

8:39 checked

8:40 In Clojure you never have to put anything into a try/catch block I think.

8:40 Even when you do something that would require such a try/catch block in Java.

8:41 Or is my understand not correct?

8:41 rhickey: you want checked exceptions for Clojure?

8:42 gnuvince: God no!

8:42 AWizzArd: I don't know, but I would like to hear your opinion (as you have much more Java experience than I have). Could that make sense? Would that help programmers?

8:42 rhickey: Checked exceptions are a horrible misfeature of Java

8:43 AWizzArd: oh, I see

8:45 gnuvince: AWizzArd: it makes no sense to force people to handle exceptions if they don't know how they should handle them; you just end up rethrowing them.

8:46 AWizzArd: Hmm I see. At a first glance it sounded as if this could improve the program safety. The programmer would have to think about her program would continue in an exceptional situation.

8:46 Chousuke: you just end up adding the same boilerplate code every time :(

8:46 AWizzArd: +how

8:46 I see, didn't know that.

8:47 Chousuke: I'm glad I have strong hair, otherwise I might already be bald from all the hair-ripping I've done when dealing with java exception handling. :)

8:47 thoughtpolice: rhickey: seems to be something like that - http://paste.lisp.org/display/72026

8:47 AWizzArd: The intentions of Sun were good, but practice showed they were wrong.

8:50 thoughtpolice: rhickey: but no real specific question; I was trying to learn clojure so I decided to look around for some java related stuff I could harness from it; might go back to hadoop or something since android no workee :(

8:55 rhickey: thoughtpolice: android is an eventual target, but anything involving bytecode transformation might need work, since many of these tools are looking for the output of javac

8:56 thoughtpolice: ok - that's the same thing I saw, will look into it when I get time

8:56 Chouser: wouldn't the dynamic loader that gives applets fits similarly be a problem for android?

9:30 jdz: I think assert macro should accept a message argument so that a message with runtime values (instead of test form) could be generated. something along the lines of this: http://paste.lisp.org/display/72027

9:31 could be used like: (let [n 42] (assert (odd? n) "number should be odd: " n))

9:33 the addition is too small i don't want to bother the mailing list...

9:33 somebody with commit rights could commit it; or tell me to bugger off :)

9:33 (in which case i'd go to mailing list, anyway :)

9:34 Chouser: only rhickey has commit rights

9:34 jdz: fair enough

9:34 then i send him an email if i don't get flamed too much

9:35 and if he does not see it here

9:40 RSchulz: jdz: You can do this: (let [n 42] (if-not (odd? n) (throw (new Exception (str "number should be odd: " n)))))

9:40 Not as concise, of course.

9:40 Or you could just write your own "assert2" or some such.

9:41 jdz: and i can have my own extended version of assert, too.

9:41 but there is a good reason why i think it should be in the clojure.

9:41 and it's backward compatible.

9:42 the only question is about the message formatting.

9:42 RSchulz: Like Chouser said, propose it. Rich won't flame you.

9:42 But not here, naturally. On the list.

9:43 jdz: yes, looks like the list is the right place to go after all.

9:44 no change is small enough not to deserve an extended discussion :)

9:52 hiredman: clojurebot: rhickey?

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

9:53 hiredman: clojurebot: rhickey is a T-1000 sent from the future

9:53 clojurebot: c'est bon!

9:57 RSchulz: hiredman: You need to teach clojurebot some critical thinking skills...

9:58 hiredman: ?

9:58 RSchulz: clojurebot: hiredman is a three-toed sloth

9:58 clojurebot: Roger.

9:58 RSchulz: It's a bit gullible, no?

9:59 hiredman: damn it, you just overwrote the two previous entries for hiredman

9:59 RSchulz: What were they?

9:59 drewr: clojurebot doesn't version?

9:59 AWizzArd: We'll never find out...

9:59 hiredman: clojurebot: hiredman is also slightly retarded

9:59 clojurebot: c'est bon!

10:00 RSchulz: That's an idea. You could give it a syntax (maybe a leading +) that causes it to add to an existing entry.

10:00 hiredman: if you use also, it adds multiple entries to something, and then randomly picks one

10:01 clojurebot: hiredman?

10:01 clojurebot: hiredman is slightly retarded

10:01 RSchulz: If "also" appears anywhere in the statement?

10:01 hiredman: if also appears after is

10:01 is also

10:01 RSchulz: Ah. But your "is also" displaced the previous record.

10:02 hiredman: do

10:02 no

10:02 is also turn the record into a vector containing multiple records

10:02 turned

10:02 at lookup one record is randomly chosen from the vector

10:02 danlarkin: clojurebot: hiredman?

10:02 clojurebot: hiredman is slightly retarded

10:03 danlarkin: clojurebot: hiredman?

10:03 clojurebot: hiredman is slightly retarded

10:03 danlarkin: :o

10:03 RSchulz: clojurebot: braindump

10:03 clojurebot: Titim gan �ir� ort.

10:03 RSchulz: clojurebot: braindump?

10:03 clojurebot: It's greek to me.

10:03 hiredman: spaces

10:03 RSchulz: clojurebot: brain dump?

10:03 clojurebot: brain dump is http://clj.thelastcitadel.com/clojurebot

10:03 RSchulz: Service Temporarily Unavailable

10:03 hiredman: oh

10:03 RSchulz: The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

10:04 Damn computers. Can't live with 'em, can't live without 'em.

10:04 hiredman: should be good now

10:04 RSchulz: Still STU

10:04 hiredman: server lost power last night

10:04 RSchulz: There we go.

10:05 hiredman: hmmm

10:05 RSchulz: So the brain dump shows the keys but not the associated answers?

10:05 hiredman: click on the keys

10:05 it still shows the old entries

10:05 RSchulz: Slick.

10:05 It looks like plain text, but it's actually super-fancy AJAX...

10:06 The entry you added for rhickey doesn't seem to be there

10:07 hiredman: refresh

10:07 RSchulz: Weird. It's there now.

10:08 hiredman: compojure is running in a different jvm then clojurebot, so it slurps up the clojurebot.is file, that clojurebot writes every, I dunno, maybe ten minutes, or whenever I manually run (dumpdicts) like I just did

10:09 RSchulz: "It's always something."

10:09 rfgpfeiffer: is there a powerset function for sets?

10:10 cemerick: rhickey: this is an interesting development: http://www.bitbucket.org/stefanrusek/xronos/wiki/Home

10:11 RSchulz: rfgpfeiffer: I don't think so. In Clojure Contrib there are some simple set utilities, but I don't see a powerset there.

10:11 rfgpfeiffer: Is there a canonical FP algorithm for computing powersets?

10:12 gnuvince: You can use the binary trick

10:12 that works best with collections with O(1) access time

10:12 rfgpfeiffer: RSchulz: when the set implements seq, then yes

10:13 rhickey: cemerick: I've seen that - no copyright/license etc, still considering a response

10:13 RSchulz: gnuvince: What's "the binary trick?"

10:13 Chouser: rhickey: it claims BSD license

10:13 RSchulz: cemerick: I know what CLR is. What's DLR?

10:14 cemerick: RSchulz: Dynamic Runtime Library, I believe

10:14 rhickey: Chouser: but is it free of Clojure-copyrighted material?

10:14 RSchulz: Which itself runs on the CLR?

10:14 cemerick: yeah

10:14 blackdog: it's what ironpython is based on - an extension to clr

10:14 cemerick: an established way for dynamic languages to hook into the platform, APIs, etc

10:14 Chousuke: RSchulz: dynamic language runtime

10:14 I think :P

10:14 cemerick: ugh, yes, runtime.

10:15 Still tired, I guess -- mixing up my R's and L's :-P

10:15 gnuvince: RSchulz: http://en.wikipedia.org/wiki/Powerset#Representing_subsets_as_functions

10:15 RSchulz: gnuvince: Thanks.

10:16 gnuvince: RSchulz: I have a small implementation

10:16 I'll paste it

10:16 cemerick: rhickey: I actually didn't notice the licensing on the Xronos bit -- it's an acceptable usage of clojure, assuming he dots the i's with the license and copyright, yes?

10:16 RSchulz: Great.

10:17 rhickey: cemerick: he can't relicense Clojure as BSD nor leave off copyright notices

10:17 RSchulz: I have Java code for the four basic set algorithms.

10:17 ...operations...

10:17 gnuvince: Hmmm

10:17 cemerick: rhickey: sure, that's definitely a no-no

10:17 gnuvince: is paste.lisp having problems?

10:17 blackdog: is it still clojure though? i suppose that'll be the argument

10:17 rhickey: cemerick: that's what it looks like right now

10:17 Chouser: rhickey: spot check on his PHM, looks hand-written and perhaps not even directly translated from Clojure

10:17 danlarkin: blackdog: it only has to be based on clojure

10:17 blackdog: to be a derivative work

10:18 blackdog: ok

10:18 drewolson: hey all, i'm trying to write a lazy prime seive and i thought this was it: http://gist.github.com/35146

10:18 but i get a heap exception if i do (nth (primes) 10000)

10:18 gnuvince: RSchulz: http://pastebin.ca/1283606

10:18 drewolson: where do i lose the laziness?

10:18 RSchulz: Thanks.

10:18 How many of these "paste" sites are there??

10:19 cemerick: I'm guessing he's just not aware of the issues around the license and copyright notices, etc. Otherwise, he wouldn't have even specified that it was a derivative of clojure.

10:19 Chouser: rhickey: for example his PHM.seq() appears to copy the entire think into a List.

10:19 thing

10:19 RSchulz: gnuvince: Wouldn't it be possible to collaps those two (for ...) forms into one?

10:20 gnuvince: RSchulz: probably; I was still a wet-behind-the-ears Clojurist when I wrote that.

10:20 RSchulz: Anyway, that's cute. Thanks again.

10:20 Chouser: drewolson: http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf

10:21 RSchulz: 'Cept where are the individual sets comprising the powerset created?

10:21 drewolson: Chouser: thanks...is the gist of the paper that i haven't actually implemented the "true" algorithm?

10:22 Chouser: drewolson: it's that what you're implementing is much slower than a sieve.

10:22 drewolson: i see

10:22 Chouser: drewolson: just like mine and everyone else's lazy prime sequence.

10:22 RSchulz: Well, it works. I'll have to figure out how. (Don't tell me!)

10:22 drewolson: :)

10:22 but i still don't understand how it's not lazy

10:23 i guess that's my main question

10:23 Chouser: the paper has an algorithm (in haskell :-P) for a fast lazy prime seq.

10:23 drewolson: oh man, haskell is very foreign to me

10:23 i'll give it a shot

10:24 gnuvince: drewolson: get Real World Haskell

10:24 mfredrickson: drewolson: i have a version in scheme if you want it

10:24 Chouser: yeah, I meant to try, but the haskell is pretty impenetrable for me.

10:24 gnuvince: drewolson: http://book.realworldhaskell.org/read

10:25 drewolson: i'm actually less interested in the "true" implementation than why this implementation is not lazy

10:25 where did i lose laziness?

10:25 RSchulz: gnuvince: One last thing: It would probably be better if the empty subset that's part of every powerset were '(), not nil, wouldn't it?

10:25 AWizzArd: Chouser: F# is maybe the easier step after Clojure, and only then Haskell.

10:25 Chousuke: RSchulz: do you mean #{}? :)

10:25 drewolson: gnuvince: thanks, i'll check that out

10:25 RSchulz: Well it doesn't return sets, it returns lists.

10:26 user=> (powerset ['a 'b 'c])

10:26 (nil (a) (b) (a b) (c) (a c) (b c) (a b c))

10:26 Chousuke: hm

10:26 Chouser: drewolson: as to why yours is blowing the heap, cgrand just taught me this a couple days ago. I'll find the link...

10:26 Chousuke: are you sure those are lists and not just sequences?

10:26 drewolson: Chouser: great, thanks :)

10:26 RSchulz: user=> (map class (powerset ['a 'b 'c]))

10:26 (nil clojure.lang.LazyCons clojure.lang.LazyCons clojure.lang.LazyCons clojure.lang.LazyCons clojure.lang.LazyCons clojure.lang.LazyCons clojure.lang.LazyCons)

10:27 gnuvince: RSchulz: they're lazy cons

10:27 I guess you just saw that )

10:27 :)

10:28 Chousuke: they should be sets, but that would destroy the laziness I guess :/

10:28 Chouser: drewolson: http://groups.google.com/group/clojure/msg/5a543d1a75c5fa28 -- but reading it again, it's a little harder to understand than I remember. feel free to ask more questions. :-)

10:28 RSchulz: The "binary trick" (as implemented, anyway) relies on them being indexable collections.

10:28 drewolson: Chouser: i'm sure i will

10:28 kyleburton: could someone assist me with trying the compile example from: http://clojure.org/compilation?

10:29 when I attempt to call (compile 'app.hello) I get: java.io.IOException: No such file or directory (hello.clj:2)

10:29 though a (require 'app.hello) succeeds (results in nil)

10:30 which I think implies that the classpath is right

10:30 gnuvince: RSchulz: yes.

10:31 RSchulz: there is another recursive way to do it, but I never got my head around it.

10:31 jdz: kyleburton: not really. make sure the [created] 'classes' folder is in classpath, too.

10:31 kyleburton: jdz: will try, thank you

10:31 drewolson: Chouser: wow, that is confusing...sees counter-intuative that storing the result in a let would keep the laziness

10:32 jdz: kyleburton: make sure it is in classpath and *exists* before compiling.

10:32 before launching clojure that is

10:32 RSchulz: If I was doing it in Java, I'd probably dump an arbitrary set into an array do the binary trick from there. I'd probably also generate the resulting (sub-)sets on an as-needed basis in the contains(...) and iterator methods. Assuming that would work for the full complement of the Set interface.

10:32 Chousuke: rhickey: about that Xronos thing... the clojure licence is compatible with BSD, isn't it? So providing they add the CPL copyright/licence notices, they could still mix the BSD-licenced code with clojure's CPL code, right?

10:33 kyleburton: jdz: that got me to another error: java.lang.RuntimeException: java.lang.ClassNotFoundException: app.hello$_main__1316 (NO_SOURCE_FILE:0)

10:33 jdz: kyleburton: read what i wrote after.

10:33 kyleburton: jdz: it exists, tho I my have neglected to add-classpath...thanks

10:34 jdz: i think Clojure should warn if the classes folder is not in classpath...

10:34 kyleburton: jdz: thank you, it compiled

10:34 rfgpfeiffer: powerset for seqs: http://gist.github.com/35157

10:35 rhickey: Chousuke: anything derived from Clojure must be CPL, it can be combined with anything (except GPL, but that's GPL's choice)

10:35 Chouser: Chousuke: that may be, but the page implies that all of Xronos is BSD, which can only be true if there's nothing clojure-derived in it.

10:36 AWizzArd: aha, that's how it works

10:36 RSchulz: rfgpfeiffer: I didn't realize let's destructuring allowed optional elements via &! That's very cool.

10:37 Chousuke: Chouser: I suppose that need to be investigated.

10:37 Chouser: RSchulz: the one thing named after & is bound to a seq

10:37 AWizzArd: I think you can binding and destructuring is everywhere the same, in defn, fn, let, binding, with the exception of def

10:37 danlarkin: It could just be a clean room re-implementation of clojure

10:38 AWizzArd: RSchulz: Like &rest in Common Lisp.

10:38 RSchulz: Yes. It makes perfect sense, but I don't think I've seen it before or thought of it. It's good to know, obviously.

10:38 Chouser: binding does not support destructuring

10:38 RSchulz: Right. But does CL allow arbitray lamba lists in its let forms?

10:38 AWizzArd: ok, so binding and def are special in that regard then

10:38 drewolson: rfgpfeiffer: my brain hurts, but very cool

10:38 jdz: RSchulz: there is destructuring-bind

10:39 AWizzArd: RSchulz: CL does not do implicit destructuring if you mean this. There is.. what jdz said.

10:39 RSchulz: In CL, you mean. I think I remember that, now.

10:40 rhickey: danlarkin: this doesn't seem clean room: http://www.bitbucket.org/stefanrusek/xronos/src/tip/System.Xronos/Language/

10:41 blackdog: quite up to date though with atom and swap!

10:41 Chouser: rhickey: I'm not sure. The contents of the files seem very weakly informed by Clojure, if at all.

10:41 rhickey: Chouser: I agree, to the point of missing the point of persistent data structures in many cases

10:42 Chouser: yes

10:42 gnuvince: What does a right arrow -> indicate in maths? Implies?

10:42 danlarkin: gnuvince: if

10:42 rhickey: At some point there may be a proper targeting of the CLR from Clojure officially, making that effort moot

10:43 Chouser: rhickey: such that your objection, if any, should be over the mis-use of the name Clojure more than the mis-use of CPL code.

10:43 RSchulz: rhickey: How much attention have you paid to making a CLR-based Clojure possible?

10:43 Chouser: s/should/could almost/

10:44 RSchulz: early versions of Clojure targetted both JVM and CLR

10:44 Chousuke: RSchulz: if you look at the SVN history, there once was one :p

10:44 RSchulz: Just like Scala, yes?

10:44 (In that one regard!)

10:47 AWizzArd: maybe in 1-2 years someone will start a Clojure version for .net

10:48 rhickey: RSchulz: a CLR version is definitely possible, sans generics

10:49 Chouser: this looks less clean room: http://www.bitbucket.org/stefanrusek/xronos/src/tip/System.Xronos/Reader.cs

10:49 rhickey: heck, Chouser's got it running in JavaScript!

10:49 RSchulz: I guess that's a good thing. Did targeting the intersection of the two virtual machines impose any extra constraints on the language design?

10:49 Chouser: for example, see line 19 and compare to line 44 of LispReader.java

10:50 rhickey: RSchulz: the object models are almost identical

10:50 RSchulz: That's trippy. Maybe when Chrome, with its supposedly super-fast VM, is mature, we can run Clojure directly in the browser.

10:50 Actually, that's extremely cool.

10:51 blackdog: RSchulz, all major browsers except IE have the same performance characteristics in the latest betas

10:51 in fact webkit is fastest right now i believe

10:51 RSchulz: So Bill C's claim that CL is the Borg of languages will have to be supplanted by Clojure being the Borg of all languages. The one, true, universal programming language. All hail Clojure!

10:51 rfgpfeiffer: RSchulz: my browser has a java plugin

10:52 RSchulz: Given that JS VMs are only getting started, one can expect considerable improvement over the next few years. All very good.

10:52 blackdog: and Chouser's version compresses to 20K or so, so it's looking good

10:52 RSchulz: Yeah, but the impedance mismatch of the Java browser plug-in makes it far from a good solution for most BBIs.

10:54 rfgpfeiffer: is it possible to make applets with clojure now?

10:54 Chouser: rfgpfeiffer: almost. :-)

10:56 rfgpfeiffer: is the applet class loader the problem?

10:57 AWizzArd: Maybe when applets work one can also write JavaFX apps.

10:57 Chouser: I think the problem is the security restrictions preventing Clojure from creating its own classloader.

10:58 * rhickey added: "make RT.ROOT_CLASSLOADER load on demand, possibly never if AOT compiled" to help wanted list

10:58 rhickey: http://richhickey.backpackit.com/pub/1597914

10:59 clojurebot: todo?

10:59 clojurebot: todo is http://richhickey.backpackit.com/pub/1597914

10:59 * Chouser tries to resist

10:59 rhickey: Version 1.0 punch list there too

11:01 RSchulz: rhickey: Does the isa? implementation use a fast subtype hierarchy test? Or does it traverse the inheritance DAG?

11:02 rhickey: RSchulz: it caches lookups

11:02 so fast

11:03 RSchulz: Does it cache both positive and negative results on a argument-pair (per hierarchy) basis?

11:04 stuarthalloway: morning all

11:04 gnuvince: Hi stu

11:04 RSchulz: Hi stuarthalloway. Shouldn't you be writing something??

11:04 rhickey: RSchulz: see MultiFn.java

11:04 RSchulz: rhickey: OK.

11:05 stuarthalloway: not working on the book today -- I am porting the macro chapters of "On Lisp" into Clojure

11:05 danm_: nifty

11:05 stuarthalloway: and I have hit a snag :-)

11:05 Chouser: stuarthalloway: others have started on that -- not sure how far they've gotten.

11:05 stuarthalloway: when learning, it is ok to reinvent the wheel

11:06 Chouser: indeed

11:06 stuarthalloway: but here is my question

11:06 pg has a variant of when-let that does not introduce a genysm for the bound symbol

11:06 Clojure

11:07 introduces a symbol (temp#) presumably to prevent double-evaluation

11:07 mchurch: I've got a question about the Clojure runtime. I know that SBCL's reader interns a symbol when it encounters it. Clojure seems not to do this; am I correct?

11:07 RSchulz: How come every question I ask here is answered five minutes later as I listen to rhickey's Clojure for Lisp Programmer's talk?

11:08 rhickey: mchurch: kind of a trick question as CL's symbols are more like Clojure's vars, but yes, no interning by the Clojure reader

11:08 stuarthalloway: but I cannot craft a scenario where this can possibly happen, because the destructuring kicks out anything that isn't a literal (line 2283 of core.clj)

11:09 RSchulz: and I double-dare you to find the video where rhickey has already answered my question :-)

11:09 Chouser: stuarthalloway: you're talking about his 'when-bind' ?

11:09 stuarthalloway: Chouser; yes

11:09 rhickey: paste please

11:09 stuarthalloway: rhickey: me?

11:10 rhickey: stuarthalloway: yes please

11:10 mchurch: rhickey: Ok, great. The reason I am asking is that I'm writing an RPC engine in multiple languages, and on the Lisp side, I have to serve out a package so as to avoid interning a bunch of garbage symbols.

11:10 Chouser: stuarthalloway: his doesn't double-evaluate -- do you need the capturing effect or something?

11:11 mchurch: Which would, over the long term, have the effect of a memory leak. So you're saying that there's no need to worry about that with keywords/symbols, because an uninterned symbol will stay uninterned?

11:12 stuarthalloway: http://paste.lisp.org/display/72036

11:12 rhickey: mchurch: there's no such thing as an interned symbol, per se

11:13 Chouser: rhickey: are keywords not interened somewhere?

11:13 stuarthalloway: sorry so slow -- when I tried to choose #clojure at paste.lisp.org something went sideways

11:13 Chouser: pg

11:13 (damn fat fingers) pg version expands ,var twice

11:14 Clojure version avoids this, but I cannot see when it would be a problem

11:14 rhickey: Chouser: yes, keywords are, but not in a package. In CL, if you read (a b c) in 10 different packages you'd have 30 interned symbols, in Clojure 3 interned strings (the names of symbols are interned) and no lingering symbols

11:15 Chouser: but that's just then name. Clojure uses temp# I think for destructuring.

11:15 rhickey: ok.

11:15 stuarthalloway: Chouser: convince me with a scenario where temp# is needed

11:15 mchurch: rhickey: So if the RPC engine gets hit with garbage keywords, there will be memory bloat?

11:16 Chouser: stuarthalloway: (defn foo [x] (when-let [[a b] x] (list a b)))

11:16 rhickey: mchurch: they'll hang around, yes

11:17 mchurch: rhickey: Ok, got it. Is there any way to get rid of them to trim the memory footprint?

11:20 Chouser: http://paste.lisp.org/display/72038 -- pg's when-bind

11:20 mchurch: I'm thinking about an engine with a lifespan of years, receiving many calls, so there's a lot of time for garbage to accumulate in the event of error.

11:22 rhickey: mchurch: it would probably require some kind of weak references on my end, would have to think about that

11:25 stuarthalloway: Chouser: why not http://paste.lisp.org/display/72038#1? No temp#

11:28 My contention is that the temp# if only needed if you can make the name side of the binding form have side effects

11:28 which my simple efforts have failed to accomplish because line 2283 of core.clj throws out any form that could possibly make trouble

11:29 Chouser: stuarthalloway: very good -- you've proved my example was insufficient. :-)

11:29 Try this: (when-bind [[a & b] [1 2]] (list a b))

11:30 so not a side-effect, but an expression that's a valid binding form but not a valid evaluation form.

11:30 stuarthalloway: Chouser: terrific, thanks!

11:33 * stuarthalloway is making the macros chapter and the binding section of the book longer...

11:34 RSchulz: I thought you weren't writing today?

11:35 stuarthalloway: RSchulz: have absorbed more info from Chouser, must make changes :-)

11:36 * Chouser continues to break the work of others.

11:36 stuarthalloway: actually I am going to have to draw a line somewhere. Does the issue we were just discussing really belong in a 225-250 page intro book?

11:37 RSchulz: What's the page limit you're operating under?

11:37 Chouser: you're not going to make it in under 250 pages, are you?

11:37 stuarthalloway: much past 250 would change details for the publisher

11:37 RSchulz: I think you should try to beat the Programming Scala book. It's 736 pages...

11:37 stuarthalloway: they're agile, they can deal, but they'll need to hear the voice of readers

11:37 Chouser: By my count, 211 pages with 5 chapters to go.

11:38 danm_: 736.. haha

11:38 RSchulz: I kid you not!

11:38 stuarthalloway: like beloved reviewers clearly saying "book must have more coverage of X, Y, Z...." :-)

11:38 blackdog: but clojure is succinct :P

11:39 acieroid: Hi

11:39 hiredman: RSchulz: but how much of that is just the type system?

11:39 stuarthalloway: I can't believe how inept I felt at Scala after reading those 736 pages. So ... much ... stuff ... I hope readers of the Clojure book won't feel that way.

11:39 RSchulz: Yeah. That Scala... It's rococo

11:39 Chouser: stuarthalloway: to answer your question, I don't know that it does.

11:39 acieroid: what's the equivalent of lisp's append function with clojure ?

11:40 RSchulz: acieroid: into

11:40 (doc into)

11:40 clojurebot: Returns a new coll consisting of to-coll with all of the items of from-coll conjoined.; arglists ([to from])

11:40 acieroid: thanks

11:40 nice bot :D

11:40 RSchulz: Keep in mind that depending on kind of collection given, the position of the added entries will vary.

11:40 Thank hiredman for that.

11:40 clojurebot: hiredman?

11:40 clojurebot: hiredman is slightly retarded

11:41 duck1123: clojurebot: botsnack

11:41 clojurebot: thanks; that was delicious. (nom nom nom)

11:41 * hiredman dies

11:41 RSchulz: I still think we're spoiling clojurebot.

11:41 Chouser: stuarthalloway: for it to matter, you'd need to (a) be writing a macro that (b) binds a form that is (c) user-supplied that (d) uses destructuring.

11:41 hiredman: clojurebot: could you explain the nature of your creator?

11:41 clojurebot: excusez-moi

11:41 hiredman: hmmm

11:42 Chouser: stuarthalloway: and having lept those hurdles, you get a relatively clear "Unable to resolve symbol: &" error which can be resolved with one extra 'let'

11:43 stuarthalloway: but clearly the book must have more coverage of seque. :-)

11:44 rhickey: seque?

11:44 Chouser: (doc seque)

11:44 clojurebot: Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer.; arglists ([s] [n-or-q s])

11:44 RSchulz: Those funky "human transporters."

11:44 Chouser: rhickey?

11:44 rhickey: Chouser: I know what it does, just questioning its inclusion

11:45 is it really in there?

11:45 in the book?

11:45 Chouser: oh! just a joke. Having no coverage of seque is entirely appropriate.

11:45 rhickey: right

11:45 whew!

11:45 Chouser: :-)

11:46 rhickey: just skimmed the macro section - I'd rather implement macros than explain them

11:46 Chouser: I carefully used exactly the same working as stuarthalloway's earlier commend about "beloved reviewers" and also added a smiley.

11:47 yes! my blog post on 'doseq' was torture for me -- probably for readers as well. :-P

11:49 rfgpfeiffer: rhickey: should the datalog from your todo be implemented in clojure

11:50 rhickey: rfgpfeiffer: wrapper on http://iris-reasoner.org/ would be interesting too

11:52 rfgpfeiffer: seque would make writing a parallel prolog solver in clojure very easy

11:52 RSchulz: Does IRIS use a sound unifier?

11:53 clojurebot: svn rev 1155; check for static field in classname/fieldname

11:54 gp: is eval the actual cloujure-interpreter? im doing genetic programming in both clojure and python and pythons eval seems somewhat limited, i cant def functions for example

11:55 why does: (eval '((defn sq [x] (* x x)) (sq 12))) return 20736 (=12^4)?

11:55 Chouser: gp: there is no clojure interpreter.

11:55 gp: compiler?

11:55 i thought interactive == interpreted

11:55 Chouser: yes, eval will compile and evaluate the expression.

11:56 mehrheit: gp: you call the function two times there

11:56 Chouser: I know, it's cool, right? Each thing you type at the repl is complied to bytecode on the spot and handed off to the JVM to run.

11:57 mehrheit: gp: (F ...) is a function call, defn returns the defined function (the var more exactly, but the behavior is the same in this case) which occurs in the function position of the list you pass to eval

11:57 gp: so you get (sq (sq 12))

11:57 gp: ah i see (eval '((defn sq [x] (* x x)) 12))

11:58 mehrheit: gp: it should probably be (do (defn sq ...) (seq 12)), since do sequences operations

11:58 err, s/seq/sq

11:58 hiredman: or use fn instead of defn

12:05 gp: hmm i cane val anything it seems so it is more complete than pythons eval

12:05 Chouser: gp: python splits expressions and statements. Clojure does not.

12:08 gp: to work with python statements you'd have to use compile() and have to specify 'exec', 'eval', or 'single'

12:09 rfgpfeiffer: gp: eval is a function that evaluates expressions, so it can be used in another expression

12:09 gp: exec is a statement

12:12 gp: i see

12:13 single?

12:21 i found out

12:21 well it seems Python complicates that part a lot. I did genetic algorithm in python but seems for genetic programming lisp is the sh*t

12:36 Pupeno: Hello.

12:37 what do we have in terms of unit-testing frameworks?

12:42 Lau_of_DK: Pupeno: Kotarak is working on something, check the GoogleGroup

12:45 Chouser: there's clojure.contrib.test-is

12:47 stuarthalloway: Pupeno: I have been playing with Fact today: http://paste.lisp.org/display/72042

12:47 Description of Fact: http://groups.google.com/group/clojure/browse_thread/thread/193023afbf87698d

12:47 I hope to post a blog entry later explaining that example

12:49 mchurch: Does Clojure have a TRACE facility?

13:06 danlarkin: mchurch: there's one in contrib and IIRC there was one posted to the group recently too

13:11 Pupeno: I like clojure.contrib.test-is

13:12 durka: mchurch: clojure.contrib.trace

13:12 defn --> deftrace

13:17 notyouravgjoel: Am I doing anything wrong by running "java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl"? the current directory has bothy jline-0.9.94.jar and clojure.jar

13:22 ughhhh

13:22 nm

13:34 RSchulz: notyouravgjoel: What platform do you use?

13:35 notyouravgjoel: got it fixed =)

13:35 but, for reference, I'm on windows right now

13:35 RSchulz: OK. But if you're on Linux (or maybe Mac, too), I recommend rlwrap over jLine.

13:35 Probably rlwrap works on Cygwin, too, but I don't really know.

13:57 AWizzArd: In there something like CLs integer-length in Clojure/Java?

13:57 http://www.lispworks.com/documentation/HyperSpec/Body/f_intege.htm

14:02 rfgpfeiffer: logarithms?

14:02 base 2

14:03 AWizzArd: There is an example implementation in the HS.

14:04 But maybe Java already has something like that.

14:13 acieroid: hum

14:13 with other lisps than clojure, when there is an error on the evaluation, slime put the error buffer on the screen

14:13 but not with clojure

14:14 so I have to C-x b every time :x

14:15 drewr: That might not be implemented yet.

14:15 acieroid: ok

14:18 what's the default namespace ?

14:18 drewr: There isn't really one. I suppose user is the closest thing.

14:19 acieroid: but, if I use in-ns, and then try to use a simple function like +, it doesn't work

14:19 hiredman: acieroid: you need to refer clojure.core

14:19 acieroid: ah

14:19 I tried clojure, not clojure.core

14:20 hiredman: (clojure.core/refer 'clojure.core)

14:20 it got renamed

14:20 acieroid: yes, thanks

14:20 drewr: Ah, yes. The clojure namespace. :-)

14:23 acieroid: clojure is very nice btw, I really like it :)

14:28 drewr: acieroid: I do too.

14:34 gp: clojure is the shiznit

14:51 if i wrap loops will the vars be reassaisned then?

14:53 or i have to recur back to the oute rloop hmm

14:59 stuarthalloway: On Lisp -> Clojure, chapter 7: http://blog.thinkrelevance.com/2008/12/12/on-lisp-clojure-chapter-7

14:59 feedback welcomes

15:00 JavaScript library that syntax-colors Clojure correctly would also be very welcome

15:01 Chousuke: well there's one used on clojure.org ... I remember seeing the config for that somewhere :/

15:01 unfortunately I don't remember WHERE.

15:06 billc: stuarthalloway: Have a look at the Clojure site's one: http://clojure.org/file/list (clojure.js, code_highlighter.js, et al)

15:06 stuarthalloway: billc: thanks, will do

15:06 clojurebot: svn rev 1156; fixed tagToClass for chars

15:54 danm_: is merge the appropriate way to update a map?

15:55 drewr: danm_: It's how I do it. You can use conj too.

15:55 danm_: to associate a key with a different value?

15:56 drewr: Sure.

15:56 user> (conj {:foo 1} {:foo 2})

15:56 {:foo 2}

15:56 danm_: ok

15:56 thanks

15:56 I suppose I could have typed that at the repl

15:56 drewr: ;-)

15:57 danm_: I'm trying to create an in memory database, and I can't help but feel as though I'm fighting the current, so to speak

15:57 side effects, oh my

15:58 drewr: Paste some code and maybe we can help.

15:59 http://paste.lisp.org/new/clojure

16:00 danm_: thanks

16:03 hmm, goes to http://paste.lisp.org/submit and it's a blank screen

16:03 no actibity

16:03 activity :P

16:03 Chouser: yeah, sometimes the channel-assignment thing breaks. go back and choose "none"

16:03 danm_: ok

16:03 Chouser: then post the url here manually

16:04 danm_: http://paste.lisp.org/display/72062

16:04 thanks

16:06 dq is a structmap

16:06 emacs gets really slow when I run that function 2230times ;)

16:07 Chouser: you can use 'alter' there, instead of 'ref-set', or probably even 'commute'

16:08 danm_: obviously, have a few things to learn about refs and such

16:08 thanks

16:08 drewr: You can also use (dq :date). Maps are funcallable.

16:10 Chousuke: or (:date dq) ;)

16:11 danm_: drewr: ahh, sweet

16:11 (apply list (line-seq buf))

16:12 where buf is a buffered reader reading an input stream from a url

16:12 is there something braindead about doing it that way?

16:12 Chouser: no, but why stick it in a list?

16:12 drewr: line-seq already returns a seq, which means you can do all sorts of things that listy.

16:13 that are

16:13 danm_: well, because when the function returns the stream gets closed

16:13 with-open

16:14 drewr: Hm. I had that issue with a ResultSet macro the other day.

16:14 I ended up doing (into {} (resultset-seq ...)) to accomplish the same thing.

16:15 danm_: thanks for the help

16:16 triddell: Is there a library/approach in clojure for creating xml? Groovy has a builder syntax which make is very easy to generate xml/xhtml and I wanted to port some of this to clojure.

16:18 clojurebot: svn rev 1155; check for static field in classname/fieldname

16:18 svn rev 1156; fixed tagToClass for chars

16:18 hiredman: grrr

16:18 gp: One thing I find annoying with dynamic languages is that I find a need to dicument types. like I might want a descriptive name but to really describe what should be passed then I need ridiculous names for variables like all-vars-all-values-vector-map

16:19 drewr: gp: metadata.

16:19 Chouser: or comments

16:19 or doc strings

16:19 hiredman: "pass in whatever works"

16:19 drewr: Or DWIM. :-)

16:20 triddell: also, to clarify, when I said "port", I meant port existing code that used this Groovy feature to clojure, not port this functionality to clojure (if something like it doesn't exist)

16:21 gp: (defn f "docstring" [args] ...) right? where do i stash metadata?

16:22 drewr: triddell: There's no xml-generating code yet that I know of. I've made my own around javax.xml.

16:22 It'd be great to have something functional that's standard.

16:23 gp: is there a way to have default/optional arguments? like in python def f(x,y=10): ...

16:24 triddell: drewr: thanks, I hadn't seen anything yet (in irc or on the list) but I also wasn't really looking until now

16:24 drewr: gp: Look at http://clojure.org/special_forms

16:25 gp: For the metadata, not for default args.

16:25 (defn foo #^{:bar :baz} :quux)

16:26 mfredrickson: clojurebot: keyword arguments?

16:26 clojurebot: keyword arguments is http://groups.google.com/group/clojure/msg/51bb53ca077154f8

16:26 mfredrickson: gp: see clojurebot

16:27 others can confirm, but clojure maintains Java's function call interface, so no keywords/defaults

16:28 you could roll your own ruby style by passing in a hash as the last argument by convention

16:31 Chouser: triddell: there are a few ideas mentioned here: http://groups.google.com/group/clojure/browse_thread/thread/ab7a6a7a14575a96/55565925939312b3

16:31 triddell: here's one http://github.com/mmcgrana/clj-html/tree/master

16:32 there are other ones around... one in webjure, another in compojure.

16:33 the thing is, it's pretty easy to write a simple, slow, weakly-featured template library in Clojure, so many of us have done just that. :-/

16:33 triddell: I'll check those out. thx

16:36 AWizzArd: Chouser: this posted example uses a template engine that went wrong, like so many others.

16:37 Because it allows you to put code into the template.

16:37 This means that people will do it.

16:38 hiredman: I really like compojure's html generating dingus

16:38 Chouser: AWizzArd: The only way to avoid that is with a new non-clojure language, right?

16:38 AWizzArd: Rifes engine for example has really no logic at all embedded, not even presentation logic, which is a fine thing imo.

16:39 hiredman: you make vectors and (html ...) turns it into html

16:39 AWizzArd: that would all be done in Clojure, presentation logic and business logic

16:40 hiredman: that would be okay, to have s-expressions instead of the html stuf

16:40 although s-expressions are only a subset of what html can do. But usually for most cases this should be okay.

16:41 Chouser: well, html already is something different than Clojure. I just mean I want not a single bit of logic inside the templates, which should be... templates.

16:43 hiredman: you could do that with compojure's (html ...)

16:44 AWizzArd: when writing strings you mean?

16:44 hiredman: make a function returns a template with a bunch of vars in it, and wrap it in a binding

16:44 AWizzArd: oh I see

16:44 hiredman: AWizzArd: html == strings

16:44 what are you talking about?

16:45 AWizzArd: I first thought you were talking about s-expressions being a subset of, dunno, "html-expressions"

16:45 but that would still not be the right thing, because then template stuff would be in the code

16:45 in the function that emits templates

16:45 hiredman: ...

16:46 AWizzArd: No template stuff in the code, no html in the code ever, no logic in the templates. I think this is the most clean way to do it.

16:47 hiredman: it will, infact, emit html

16:47 not templates

16:47 compojure's (html ...) takes a vector and emits html (also there is (xml ...))

16:47 gp: if i ant toloop over a range and for each loop conj somethig to a vector, which construct do you use then? loop-recur or reduce?

16:48 AWizzArd: hiredman: I don't say that this is a bad thing. I just think this is not the best way to do it. The Pretty Home Page language (php) started off like that. It was their killer feature to be able to have code in the html. Soon this made things more and more complicated, and frameworks like smarty (and others) were developed, to go away from this direction.

16:49 hiredman: AWizzArd: oh, compojure is not like at all

16:49 there is no code in the html

16:49 there is not html, until you run (html ...) on a vector

16:49 then you just have this string of html

16:49 AWizzArd: I see

16:50 although you can't compose all valid html strings with it

16:50 hiredman: (defn tpl [] (html [:html [:head] [:body foo]]))

16:51 then (binding [foo "something"] (tpl))

16:51 AWizzArd: yes, nicer than pure html for many things

16:51 hiredman: for just about everything

16:51 html bites

16:51 triddell: I just looked at the html library in compojure and I think that will do what I need. I don't need templates... just need to code generate xhtml/xml dynamically from existing data.

16:52 AWizzArd: hiredman: could it also do something like <B>Hello <I>people from</B> New York</I> city.

16:52 mehrheit: isn't that invalid?

16:52 AWizzArd: for xml invalid

16:52 for html it's okay

16:53 mehrheit: weeh

16:53 hiredman: AWizzArd: but you can get the samething by doing it sanely

16:53 AWizzArd: yes

16:53 and it's rare

16:53 hiredman: so what is the point of the garbage?

16:54 AWizzArd: Just an example that html can express more than s-expressions.

16:54 In 99% of the cases it's tons of boilerplate code, to explicitly have this closing tag. But for rare cases it allows some more expressivity.

16:55 hiredman: ...

16:55 how?

16:55 AWizzArd: As in the example that I gave above.

16:55 hiredman: how is doing it that way more "expressive" then doing it the sane way?

16:55 AWizzArd: How is Clojure more expressive than coding assembler?

16:56 of course, they all can produce equivalent results

16:56 mehrheit: in one way, by imposing certain rules, so that you cant express insane things

16:57 hiredman: anyway

16:57 mehrheit: and therefore have more space for useful things

16:57 hiredman: good lick with that

16:57 luck

16:58 ugh

17:02 AWizzArd: Do you mean space as in number of chars?

17:02 length of lines?

17:03 mehrheit: basically, yes

17:06 AWizzArd: Well, in that aspect Lisps traditionally also don't shine. The s-expression style needs lots of whitespace in front of where the code usually starts. The strength is really the code=data part.

17:07 hiredman: this small description already explains more or less all there is about templates in Rife. The logic can hopefully soon be implemented completely in Clojure: http://rifers.org/wiki/display/RIFE/GuideTemplates

17:08 mehrheit: then keypresses would fit better; with a good editor indentation is zero keypresses

17:10 AWizzArd: Yes, that's right. I just mean that it gives us a lot of weakly used space.

17:11 mehrheit: I don't think thats a lot of space

17:12 AWizzArd: okay, that's an opinion

17:14 gp: anyone know a good place where you can host your webapss for free?

17:14 just a small one, dont need any space tos tore stuff, just want show a demo.

17:24 Chouser: my gen'ed class that extends Applet includes this method for no reason that I can find: public void net.n01se.Tree.applyCompoundShape(sun.java2d.pipe.Region)

17:24 I can't find it in any of the supers of my class

17:25 a web search finds it in docs for java.awt.Window, but java.awt.Window's not in my supers and doesn't appear to actually have that method.

17:44 clojurebot: svn rev 1157; removed sharing in registerConstant

17:51 RSchulz: Chouser: Which JDK version are you using?

17:52 Chouser: java version "1.6.0_0"

17:53 I think it may be picking up that method from ComponentPeer, somehwo

17:53 somehow

17:53 RSchulz: Applet's got a pretty deep inheritance hierarchy.

17:53 Chouser: yeah, but I searched it.

17:53 RSchulz: I was thinking it might be an implementation-specific thing, like something that comes from a browser tie-in.

17:54 Chouser: (map (fn [c] (filter #(= (.getName %) "applyCompoundShape") (.getMethods c))) (supers net.n01se.Tree))

17:54 (nil nil nil nil nil nil nil nil nil)

17:55 anyway, I added an :excludes option to genclass and that seems to get me past the security warnings for appletviewer.

17:55 ...now it just does nothing at all. :-P

17:55 RSchulz: Oddly enough, IDEA's symbol lookup can't find apployCompoundShape (or applyCompound*) anywhere in my 1.6.0_11 JDK.

17:55 (Or even the properly spelled name...)

17:56 Did you really mean 1.6.0_0 ??

17:57 Chouser: java version "1.6.0_0"

17:57 OpenJDK Runtime Environment (build 1.6.0_0-b11)

17:57 OpenJDK Server VM (build 1.6.0_0-b11, mixed mode)

17:57 hm... openjdk maybe?

17:58 RSchulz: Do you recall a post you made to the Clojure list in late July, subect "gen-class patch" net.n01se shows up there.

17:58 And here: http://paste.lisp.org/display/68406

17:58 Chouser: sure -- that's a domain I use.

17:58 RSchulz: Are you sure this isn't some cruft that's specific to your setup?

17:59 OK. So a red herring then?

17:59 Chouser: ah. yeah, pretty sure.

17:59 RSchulz: But the thing is, that applyCompoundshape would appear to belong to one of your classes, then.

18:01 Chouser: well, gen-class is adding that method to my class, yes. The question is why?

18:01 RSchulz: Perspicacity?

18:01 Or is it perspicuousness?

18:01 The second one.

18:02 gp: rhickey: cant you add sum (reduce + coll) and enumerate(enumerate ["a" "b" "c"] -> [["a" 0"] ["b" 1] ["c" 2]]) to Clojure? i would guess a lot of people have it in their user.clj...

18:02 RSchulz: No. The first one.

18:02 Chouser: gp: enumerate is called clojure.contrib.seq-utils/indexed

18:04 gp: Chouser: cool

18:22 anyone can point to the link with monads in clojure?

18:24 acieroid: hmm, is there a function like lisp's format, to do some showing operations on lists (like (format t "~{~a ~}" '(some list))) ?

18:25 (and that can be applied to vectors)

18:27 Chousuke: I think someone was working on an implentation.

18:28 acieroid: m'kay

18:29 Chousuke: http://github.com/tomfaulhaber/cl-format/tree/master here's one

18:30 acieroid: thanks

18:37 ben1: i know a little scheme, but no java; where's the best place to learn clojure?

18:38 acieroid: http://writingcoding.blogspot.com/2008/06/clojure-series-table-of-contents.html is a nice example

18:38 hiredman: you don't have to learn too much java, but you need to learn to read javadoc

18:39 ben1: acieroid: looks good

18:39 ok, i'll try

18:39 thanks

18:39 hiredman: http://java.sun.com/javase/6/docs/api/java/lang/String.html

18:40 but, uh, you will need some java to read javadocs

18:43 ben1: hmm, for some reason (re-seq #"\\w+" "This string contains some tokens. Yipee!") outputs nil for me

18:43 zakwilson: ben1: I'm a Lisper with no real Java experience and I've been able to pick it up reading the Clojure and Java documentation.

18:43 Chouser: ben1: #"" rules have changed. for recent clojure, don't double-backslash

18:44 ben1: ah i see, thanks

18:45 gp: lol im writing imperative in clojure: (let (let (let (let (let ...

18:46 hiredman: :(

18:46 you could most likely move that all into a single let

18:48 karmazilla: can a single macro expand into two defs? my goal is easily defining functions that execute only once regardless of how many times they're called

18:48 hiredman: karmazilla: yes

18:48 Chouser: karmazilla: sure -- wrap a (do ...) around them

18:48 hiredman: ^-

18:50 karmazilla: super! thanks

18:50 RSchulz: karmazilla: That, or get Stuart Halloway's Programming Clojure book, where this precise example is covered in detail.

18:51 That book is in pre-release and available in PDF form.

18:51 From Pragmatic Programmers.

18:52 karmazilla: do you remember what the example is called?

18:53 zakwilson: karmazilla: see also the memoization example in the documentation for atoms.

18:53 RSchulz: It is the runonce feature needed for his Lancet (Ant driver) program.

18:54 Section 6.4: "Making Lancet Targets Run Only Once" (page 141 in beta4 of the PDF)

18:56 ben1: why doesn't (map .toLowerCase '("This" "IS" "my" "name")) work?

18:57 RSchulz: .toLowerCase isn't a Clojure function

18:57 Try this: (map .toLowerCase '("This" "IS" "my" "name"))

18:57 Woops!

18:57 Hang on.

18:57 ben1: but (.toLowerCase "fOo") works

18:57 RSchulz: (map #(.toLowerCase %) '("This" "IS" "my" "name"))

18:58 ben1: ok that works

18:58 hiredman: . does some special reader magic

18:58 ben1: so how do i know when i can use ".toLowerCase"?

18:59 RSchulz: .JavaFieldOrMethod is a special form.

18:59 Actually, that's only true of ., not of .stuff

18:59 hiredman: mostly in (.f a) or in any place that turns .f into (.f a)

19:00 so you can use .f in ->

19:00 maybe the new doto, I don't recall

19:00 RSchulz: What's that? Iget only a missing-glyph symbol.

19:00 hiredman: grrr

19:00 an irssi auto replace run amok

19:00 ->

19:00 gah

19:01 the arrow deal

19:01 RSchulz: Is that the same thing that turn my less-than into <

19:01 Chousuke: ben1: .foo can only appear as the operator in a form right now.

19:01 RSchulz: Eh? Sometimes I get &lt; when I paste <

19:01 ben1: Chousuke: ok thanks

19:01 Chousuke: ben1: of course, there are macros that make that appear untrue

19:01 hiredman: like (->)

19:01 Chousuke: or doto

19:03 RSchulz: Or ..??

19:03 (..)

19:03 Chousuke: .. is meh.

19:03 -> is better

19:04 though I remember rhickey mentioning that he might implement "auto-memfn" for .forms, so you might eventually be able to use map etc directly with java methods.

19:05 for now, just use #(.foo %) or (memfn foo)

19:13 karmazilla: how do people normally build (as in compile + test + package) clojure programs?

19:15 danlarkin: Hm this is confusing me... javadoc for an object says it should have a method... method is listed when I use (show obj) but when I try (.method obj) it says no matching method found

19:17 Chouser: danlarkin: that error is also used if the arity or arg types don't match.

19:18 danlarkin: Chouser: it has arity zero, http://jparsec.codehaus.org/jparsec2/api/org/codehaus/jparsec/Terminals.html#tokenizer()

19:19 Chouser: hm. Have you tried my 'show' function?

19:21 or (filter #(= (.getName %) "tokenizer") (.getMethods (identity org.codehaus.jparsec.Terminals)))

19:23 danlarkin: http://dpaste.com/98647/

19:23 Chouser: wow

19:23 RSchulz: Show is fab!

19:24 danlarkin: confusing right?

19:25 Chouser: (.isBridge (show operators 18))

19:26 danlarkin: false

19:28 Chouser: well, I'm stumped. :-)

19:29 danlarkin: rhickey: care to weigh in?

19:30 jonafan: does clojure have a unit testing framework?

19:31 probably a dumb question

19:31 danlarkin: jonafan: clojure-contrib does

19:31 jonafan: cool

19:31 i'm trying to decide what language to learn in 2009

19:31 danlarkin: jonafan: clojure :)

19:32 gnuvince_: jonafan: what's on your list?

19:32 jonafan: hehe

19:32 Chouser: http://clojure-log.n01se.net/date/2008-12-12.html#12:36 -- unit test question

19:32 jonafan: forgive me if i consider your answer some what biased

19:32 clojure, erlang, haskell, forth, smalltalk

19:32 gnuvince_: Good choices

19:32 (though I'd change Forth for Factor)

19:33 jonafan: maybe

19:33 danlarkin: for all the hype that smalltalk gets I really dislike it

19:33 Chouser: jonafan: I started on Scala this year, but that only lasted a couple months. I'll be on clojure for a while...

19:33 gnuvince_: Factor, Clojure and Haskell would be my recommentations.

19:33 Not necessarily in that order

19:33 gp: how Is Factor interesting?

19:33 Depending on where you come form I think Haskell is the most mindexpanding.

19:34 jonafan: in 2008 i learned ocaml

19:34 Chouser: It'd be useful to be able to read Haskell.

19:34 gnuvince_: gp: many ways: it's a very minimal and powerful language, the implementation is getting extremely good, and it can teach you to think in terms of stacks.

19:34 jonafan: haskell is stricter and has monads, but they are pretty similar languages

19:34 gnuvince_: Haskell is lazier

19:34 jonafan: okay, haskell is lazier

19:34 i meant in terms of purity

19:35 gnuvince_: jonafan: in any case, your list is a very good one.

19:35 kib2: no one for Rebol ? it's awesome, really.

19:35 Chouser: jonafan: have you done any lisp before?

19:35 gnuvince_: Any one of those languages is gonna be better than another newbie learning PHP or C.

19:35 jonafan: i had scheme in college

19:35 Chouser: jonafan: Clojure won't take you a year. :-)

19:35 gnuvince_: Clojure would therefore bring something new.

19:35 jonafan: i loved it

19:36 gnuvince_: Try Clojure

19:36 It's fun :)

19:36 jonafan: yeah, but i don't want to learn it and not use it for anything

19:36 zakwilson: Clojure would be my pick of those for getting things done.

19:36 jonafan: i want to learn it and use it for whatever i feel like coding during the year

19:36 zakwilson: Factor or Haskell would probably twist your mind around more.

19:36 Though that depends on your background.

19:37 gnuvince_: jonafan: Clojure with the huge Java lib would definitely allow you to do things

19:37 jonafan: coming from ocaml, i don't feel like doing haskell yet

19:37 zakwilson: jonafan: Do you have experience with Java?

19:37 jonafan: yeah

19:37 gnuvince_: Go for Clojure ;)

19:38 zakwilson: Yeah, what gnuvince_ said.

19:38 jonafan: i definitely feel like clojure is cooler than erlang

19:38 gnuvince_: Oh definitely

19:38 Chouser: you can probably getenough clojure under your belt by June to be able to dismiss the rest by the end of the year.

19:38 zakwilson: What you already know about the Java lib, classpaths, jars and the like will carry over.

19:39 Chousuke: clojure is probably somewhat a gentler introduction to FP than haskell

19:39 gnuvince_: I don't think he needs an intro

19:39 he knows OCaml

19:39 jonafan: and scheme

19:39 Chousuke: ah, well that'll do

19:39 zakwilson: If you know OCaml, Scheme and Java, it should be very easy to pick up Clojure and start making useful things.

19:39 gnuvince_: jonafan: have you seen my (still incomplete) tutorial?

19:40 jonafan: not yet

19:40 i watched a presentation rhickey did and ran some related code

19:40 involving some ants finding a path to food

19:41 Chousuke: make sure to use a recent SVN checkout instead of the release version though.

19:41 gnuvince_: yeah

19:41 jonafan: i don't know, i'm still deciding

19:41 gnuvince_: jonafan: his presentations are awesome

19:41 Anyway, what's the worst that could happen?

19:42 jonafan: the only thing i am concerned about is the relative immaturity of the language

19:42 maybe it is fine, but there is no doubt that the other languages are more mature

19:42 gnuvince_: Fear not, it's progressing along very nicely and the implementation keeps getting better at a very fast pace.

19:42 zakwilson: There is that, and breaking changes do happen.

19:43 On the other hand, the Java library is very stable.

19:43 gnuvince_: I can tell you that the Smalltalk experience is somewhat... lacking

19:43 Chousuke: I think most of the breaking changes have already been done

19:43 gnuvince_: Squeak isn't too hot, VisualWorks either

19:43 Chousuke: AOT and gen-class

19:43 gnuvince_: Erlang still has no unicode support.

19:43 jonafan: smalltalk is a language that i have always felt like i should learn

19:43 rhickey: danlarkin: looks like something is lying, probably the JavaDoc? as notice: org.codehaus.jparsec.Lexicon.tokenizer(), but javadoc says derived from Object, no interfaces

19:44 gnuvince_: I don't think Clojure is behind the pack.

19:44 gp: is there no infintiy in Clojure?

19:44 rhickey: danlarkin: i.e. tokenizer is not declared in Terminals

19:44 jonafan: anyway, i'm going home

19:44 gnuvince_: gp: (/ (float 1) (float 0))

19:45 gp: I tried Smalltalk/Squeak once and started ona tutoria but I never really got anywhere, the whole this-language-is-also-an-OS wasn't my thing. Not that I gave it that much time.

19:45 RSchulz: Or, more directly (Float/POSITIVE_INFINITY)

19:45 Likewise for Double


19:46 gp: I find Clojure to be very mature for its age. When is 1.0 planned anyway?

19:47 zakwilson: Why is (/ 1.0 0.0) not the same as (/ (float 1) (float 0))?

19:47 Chousuke: zakwilson: 1.0 and 0.0 are Doubles

19:47 gnuvince_: What he said

19:47 danlarkin: rhickey: I see

19:47 RSchulz: I agree. Considering its chronological age, Clojure is quite advanced. That's because of Rich's diligence and the platform support provided by the JVM.

19:48 danlarkin: rhickey: but (filter #(= (.getName %) "tokenizer") (.getMethods (identity org.codehaus.jparsec.Terminals))) does return a Method

19:49 mfredrickson: RSchulz: I also think (and this is entirely my opinion) Clojure has _greatly_ benefits from learning from the mistakes of others (CL and Scheme specifically). This is entirely to rhickey and other contributors credit, but let us not forget those that have gone before. :-)

19:49 rhickey: danlarkin: but it is coming from a superclass and it's callability is dependent upon that, if nothing else for troubleshooting I'd need to know the access level of that class/interface etc

19:50 mfredrickson: from my position, Clojure fixes all the little irritations I have with Scheme without being too heavy handed

19:50 not that I wouldn't like continuations and TCO again.

19:51 Chousuke: heh

19:51 maybe we'll have all that cool stuff in clojure 2.0 someday :P

19:51 mfredrickson: i'm in no hurry

19:51 Chousuke: a lot depends on the JVM too

19:51 mfredrickson: i like the design to choice to leave out broken features

19:52 Chousuke: my understanding as well

19:53 Chousuke: JVM quirks seem to be the cause of some "warts" in clojure, but I think the benefits are worth a few compromises.

19:54 danlarkin: rhickey: is that information I can provide you? not sure what the access level is/means

19:55 mfredrickson: Chousuke: I think that is basically the value proposition of clojure: a lisp that is willing to make compromises. worse is better while still being better, if you get my drift

19:55 i realize that could describe a lot of lisps. I need to refine that

19:57 Chouser: gah, Java is frustrating. Staring at the docs to a class, and still don't have any clue how to create one.

19:59 replaca: /win 1

20:00 Chousuke: hmh, maybe clojure is a functional programming language not just in the mathematical sense :)

20:03 mfredrickson: let's see what clojure bot has to say on the matter

20:03 clojurebot: clojure?

20:03 clojurebot: clojure is a very attractive hammer with a nice heft to it

20:03 mfredrickson: there you are

20:04 gp: Chouser: ol often have the same problem, Java is so ridic bloated. Funny thing it is so well documented and still it is hard to figure out how to do simple stuff like just calling a class.

20:10 Chouser: danlarkin: well, Terminals inherits tokenizer from Lexicon, but that doesn't help me see what's failing.

20:12 Chousuke: gp: I find the problem to be often that while the information is there, it's usually in bits and pieces all over, because when you need to use a class to do something, that class uses other classes, and those use yet again other classes, et cetera

20:12 so you end up having to dig through a lot of documentation.

20:17 rhickey: Chouser: is Lexicon public? Is there JavaDoc?

20:18 gp: Chousuke: yes that was "head on the nail" or how you say it.

20:24 Chouser: I don't see any javadoc for it.

20:25 rhickey: Chouser: how are you looking into this?

20:27 Chouser: what I know about Lexicon: http://paste.lisp.org/display/72076

20:28 so clearly the javadoc is lying at least about "extends"

20:29 rhickey: (.getModifiers (identity Lexicon))

20:31 Chouser: 0

20:33 rhickey: Chouser: !?

20:33 Chouser: http://paste.lisp.org/display/72076#1

20:34 rhickey: I believe you :), just confused

20:34 danlarkin: 0 for me also

20:34 Chousuke: Chouser: is show in contrib or just floating on the web somewhere?

20:34 rhickey: not public, protected or private - must be package?

20:36 is the source for this somewhere?

20:36 Chouser: Chousuke: I guess I should put it in contrib.

20:36 back in a bit

20:36 danlarkin: rhickey: http://jparsec.codehaus.org/Downloads

20:38 Chousuke: oh crap

20:38 * Chousuke accidentally rm -r'd his git svn clone of clojure

20:38 Chouser: clojurebot: show?

20:38 clojurebot: show is http://groups.google.com/group/clojure/msg/96ed91f823305f02

20:38 Chousuke: I hope I have backups...

20:38 time machine is a bit quirky sometimes :)

20:38 RSchulz: Why this:

20:38 user=> (.getModifiers java.lang.String)

20:38 java.lang.NoSuchFieldException: getModifiers (repl-1:21)

20:39 And this:

20:39 user=> (.getModifiers (identity java.lang.String))

20:39 17

20:40 Chousuke: RSchulz: the former tries to call java.lang.String.getModifiers

20:40 the latter calls .getModifiers on the Class object

20:40 RSchulz: Ah.

20:40 Chousuke: but, hooray, I had backups.

20:41 RSchulz: Still, given what (identity) does, it's perhaps justified that one is surprised by this result...

20:41 Chousuke: well, identity just works around the fact that (.foo Classname) assumes you're calling a static method rather than a method with the Class as the argument

20:42 RSchulz: Yes. But since (identity ...) "does nothing", it's still a bit perplexing.

20:42 rhickey: clojurebot: faq #1?

20:42 clojurebot: I don't understand.

20:43 rhickey: clojurebot: faq?

20:43 clojurebot: Pardon?

20:43 danlarkin: clojurebot: FAQ #1

20:43 clojurebot: FAQ #1 is http://groups.google.com/group/clojure/msg/8fc6f0e9a5800e4b

20:43 rhickey: RSchulz: ^^

20:43 RSchulz: clojurebot's case-sensitivity is a dubious feature...

20:44 OK. Got it. But it just emphasizes the precariousness of syntactic sugar.

20:47 Clarify, if you will: Does the interpretation of dot / (. ...) depend on whether there's any white-space after it?

20:48 For example, is (. foo could be bar) different than (.foo could be bar)?

20:48 danlarkin: (.method obj) is equivalent to (. obj method)

20:49 Chousuke: so (. foo could be bar) is (.could foo be bar)

20:49 RSchulz: OK. That's one of the more tortured syntactic sugarings, no?

20:49 Chousuke: . should go away ;(

20:50 rhickey: RSchulz: only when you choose meaningless names

20:50 RSchulz: Seriously?

20:50 rhickey: how is it tortured?

20:50 RSchulz: Hmmm....

20:51 rhickey: (. target method arg)

20:51 (.method target arg)

20:51 RSchulz: Order matters. A single period and a single space necessitates an alteration of the order of the arguments (punctuation aside)?

20:52 Actually, just the space...

20:52 rhickey: RSchulz: necessitates is pejorative, this is a feature - lispy method call start with the verb

20:52 .blah is one symbol

20:53 RSchulz: I certainly don't mean "necessitates" to be perjorative, but it's ... fragile? (That seems more perjorative.)

20:53 Chouser: spaces matter in almost all languages. this really doesn't bother me.

20:53 RSchulz: (But I can't help mention that Clojure has a non-white-space white-space symbol...)

20:54 Chousuke: heh

20:54 rhickey: RSchulz: it's easiest to understand as macrology, .blah is inherently a macro:

20:54 user=> (macroexpand '(.getMethods String))

20:54 (. String getMethods)

20:54 Chousuke: (.,I,can,mess-you,up)

20:54 RSchulz: Which is to say that . followed immediately (no white-space) by a symbol is a metalinguistic schema.

20:55 rhickey: RSchulz: no, .blah is one symbol

20:55 a regular symbol

20:55 RSchulz: Exactly! "I can mess you up." would still be understood as the same as "I,would,mess,you,up"

20:55 I understand, but visual comprehension matters, too.

20:56 Chousuke: so does the reader work so that it reads ".read" and passes the *symbol* to the reader-macro-magic that transforms it?

20:56 RSchulz: And when a single space combined with a swapping of adjacent symbols yields the same thing, that's a bit ... unexpected.

20:56 rhickey: t u v and tuv are different, big deal

20:57 same as all lisps, whitespace delimited

20:57 Chousuke: RSchulz: don't forget about the third dot :)

20:57 RSchulz: How many times have you seen a spurious space before a comma or a period. Did it make you misinterpret the sentence?

20:57 Chousuke: (String.) :P

20:57 Chouser: RSchulz: just don't use (. obj method) format. It's unnecessary.

20:57 RSchulz: I'm inclined to go with that, Chouser

20:58 As long as my cat doesn't hit the space bar while I'm not looking.

20:58 Chousuke: and for static calls/fields, use / :)

20:58 RSchulz: Division?

20:58 Chousuke: no, as in Math/PI

20:58 RSchulz: ... That was meant as humor...

20:59 Chousuke: sorry, it's late :p

20:59 rhickey: Cl-USER 6 : 1 > (length '(a.b))

20:59 1

20:59 CL-USER 7 : 1 > (length '(a . b))

20:59 Error: In a call to LENGTH of (A . B), tail B is not a LIST.

20:59 Chousuke: or actually, it's almost morning ;(

20:59 RSchulz: Overloading symbology is necessary / inevitable. And a perpetual source of problems. What can we do?

20:59 Subtex?

20:59 Subtext

20:59 As in http://www.subtextual.org/

20:59 Chousuke: humans are pretty good at handling overloaded meanings though.

21:00 RSchulz: Except when they're not...

21:00 Chousuke: or rather, 1 symbol -> n meanings

21:00 RSchulz: But then, what would life be without puns and double-entendres?

21:01 Chousuke: Most like the majority of words you use have at least two meanings

21:01 Chouser: well, I've got a an applet loading, but I can't get it to draw anything.

21:01 Chousuke: most likely*

21:01 RSchulz: OK, rhickey: Now lets talk about no dotted lists...

21:01 rhickey: RSchulz: I'm not talking about dots anymore tonight

21:01 RSchulz: Just kidding, of course.

21:02 Did you consider talking to SVJUG when you're out here for Java-One? I'm sure they'd welcome you.

21:03 rhickey: I'm putting together my proposals this weekend, will propose for Conference One as well, a free conference on the preceding day

21:03 RSchulz: Free? What? Where? When?

21:03 rhickey: Same venue I think, day before Java One, SF

21:04 RSchulz: But free you say?

21:04 (I have _very_ limited resources.)

21:06 Chousuke: gah

21:07 why is sourceforge not letting me clone clojure-contrib

21:07 rhickey: http://developers.sun.com/events/communityone/

21:07 Chousuke: maybe it thinks all the checkouts are a DoS attempt :P

21:08 RSchulz: $200 doesn't equate to free for me...

21:26 mfredrickson: show of hands: academics using clojure?

21:26 * mfredrickson raises hand

21:27 mfredrickson: (I thinking of putting together a conference -- or tagging along on something)

21:35 rhickey: user=> (macroexpand '(.getMethods String))

21:35 (. (clojure.core/identity String) getMethods)

21:41 Chouser: hm!

21:42 mmcgrana: nice

21:43 clojurebot: svn rev 1158; force instance member interpretation of (.method ClassName), e.g. (.getMethods String) works

21:44 danlarkin: no more FAQ #1?!

21:45 rhickey: danlarkin: maybe:

21:45 user=> (. String getMethods)

21:45 java.lang.NoSuchFieldException: getMethods (NO_SOURCE_FILE:8)

21:45 Chouser: won't be #1 anymore though

21:46 rhickey: but if people use the preferred .member for instance and class/member for static there should be no confusion

22:04 Chouser: clojurebot: show is clojure.contrib.repl-utils/show

22:04 clojurebot: Ok.

22:12 Chouser: and that's got a 'source' that works better.

22:14 danlarkin: Chouser: woo hoo

22:15 mmcgrana: Chouser: very nice, thanks

22:17 hiredman: one of these days I'll have to grab contrib

22:18 Chouser: hiredman: or you can just write all that code again yourself.

22:18 danlarkin: hiredman: I use it all the time for checking on usage

22:18 hiredman: I have show.clj

22:18 from the ml

22:19 * Chouser conspires to improve show in contrib.

22:19 danlarkin: conspire takes an ISeq

22:20 WOW what a good joke

22:21 Chouser: heh

22:42 gp: can I use gnuplot with clojure?

22:42 matlab?

22:45 hiredman: I am sure there must be java bindings for both of those

23:18 gp: what is the dfference between #^{:doc... and (defn f "doccing" ?

23:20 Chouser: no diff

23:20 gp: and can :test be used for automatic unit-testing?

23:21 how do I call that?

23:21 Chouser: (doc test)

23:21 clojurebot: test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception; arglists ([v])

23:49 gp: the test example on special forms doesnt seem to be working

23:49 i get :no-test

23:49 when doing (test mymax)

23:51 Chouser: (test #'mymax)

Logging service provided by n01se.net