#clojure log - Dec 04 2008

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

0:31 chavo_: clojure.contrib.fcase/in-case macro uses private function in-test-case. When it is expanded in a different namespace the compiler throws an exception. Is this a bug?

0:32 timothypratley: (defmacro while[v cnd & body]

0:32 `(loop[~v ~cnd] (when ~v ~@body (recur ~cnd))))

0:33 <-- what is wrong with the v

0:34 hiredman: uh

0:34 timothypratley: (while msg (.readLine input)

0:34 (println "Read " socket msg))

0:34 hiredman: you are evaling it twice?

0:34 timothypratley: <-- doesn't work

0:35 hiredman: oh damn

0:35 hiredman: :)

0:50 replaca: Question - in "regular" lisp, to create an accumulator, the idiom is to cons up a list and reverse it, in clojure you can create a vector and just conj to it, skipping the reverse step. What's the trade-off?

1:00 timothypratley: replaca: isn't that just a fundamental trade-off question between lists and vectors in general? ie: list pop is faster than vector pop, list push is faster than vector push - ie: nothing specific to clojure or lisp as it relates to the data structure?

1:06 replaca: well, yeah, but in lisp that's not going to be the usual idiom cause

1:06 you don't have first class vectors

1:06 in clojure you can hardly avoid them

1:08 so the question is: what's the penalty for ([...] conj x) vs. (cons x (...))

1:08 if the former is close to constant time it seems nice

1:09 (THat is, when used over an accumulator, are they both clsoe to O(n) time?

1:09 or is the vector going to be a lot more expensive?

1:11 notallama: the vector is technically something like O(n log(n)), i think. but that's log base 32, so the constants quite possibly make it faster in practice than list + reverse. i dunno, though.

1:11 fyuryu: replaca: appending to the end of a vector is cheap

1:11 replaca: cool. And does that tend to be the idiom folks are using?

1:12 it does make the code a little cleaner

1:12 fyuryu: replaca: from what I've seen, yes

1:12 replaca: I find I use vectors just cause the syntax encourages me to, which makes me a little nervous :-)

1:13 Thanks!

1:13 fyuryu: at worst, appending to a vector is log32(n)

1:13 replaca: which for small things is fine

1:14 fyuryu: I say at worst, because I don't remember if there's an optimization just for appending

1:14 replaca: yeah

1:14 fyuryu: I looked at the implementation some time ago, don't remember now, sorry

1:15 replaca: that's OK -> I'm looking for idiom & not being stupid more than precise performace

2:00 timothypratley: user=> (str [1 2 3 4])

2:00 "[1 2 3 4]"

2:00 user=> (str 1 2 3 4)

2:00 "1234"

2:01 how can I make mystr behave like the 2nd when passed the 1st?

2:01 lvijay: (apply str [1 2 3 4]) ?

2:01 timothypratley: great! :)

2:01 thanks

2:48 Lau_of_DK: Morning gents

2:57 replaca: I'm new to #clojure, but I've already learned that when Lau shows up for the morning in DK, it's time for me to go to bed in San Francisco :-)

2:58 stuarthalloway: in that case I better go to be in North Carolina...

2:58 (bed)

2:58 replaca: oh yeah, you're up way too late!

2:59 but I have a little boy to take to school in the morning so there's no sleeping in

3:00 stuarthalloway: :-) night all

3:01 replaca: night!

3:15 Lau_of_DK: replaca: :)

3:18 timothypratley: I have a thread which pops messages off a queue and processes them using a multimethod which dispatches on 'message type'. Trouble is that in order for it to access outside information, I put the message definitions inside the processing thread. So when I make multiple processing threads, the functions get redefined [I stupidly thought they would be local functions but they aren't].

3:19 So I have some options... I could persist with the 'local functions' but using a let, but I can't see how I can make multimethods work inside that.

3:19 Or I could make the functions global and pass in the extra information... but again I can't add extra arguments to multimethods

3:21 Kind of a bit hard to explain I could paste the code it is about 50 lines

3:21 Lau_of_DK: Cant you simply put the shared information in a global ref to a hash-map ?

3:22 timothypratley: Lau: but how will the method know what to look up? each thread has a different 'information'

3:23 Mind if I paste it?

3:23 hiredman: lisppaste8: url

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

3:24 timothypratley pasted "MR" at http://paste.lisp.org/display/71566

3:25 timothypratley: ooo neato thanks

3:26 So yeah if you take a look there you might see what I'm trying to do, and where I've gone wrong

3:27 The important part is that client is required to process the messages

3:27 hiredman: why can't you just pass client?

3:28 timothypratley: maybe I can :) I tried modifying the multimethod example given on the website (using shapes)

3:28 adding an extra argument caused them to fail

3:28 hiredman: oh

3:29 you just need a slightly more complex dispatch function

3:29 timothypratley: ah....

3:29 so I make a function that takes 2 args

3:29 and just dispatches on the first?

3:29 hiredman: yes

3:29 timothypratley: Hmmm great!

3:29 thanks.

3:29 hiredman: clojurebot: multimethods?

3:29 clojurebot: multimethods is what separates the boys from the men.

3:29 timothypratley: :)

3:30 hiredman: <-- lame

3:31 for my multimethod stuff I just make a struct and put everything I could possibly need in it

3:36 timothypratley: hmmm actually that might be more convenient for me too

3:36 I could just assoc the extra data to the message

3:37 I'll have a look at both ways

7:31 Chouser: rhickey: good morning.

7:32 Kerris7: Good morning Chouser

7:32 Chouser: Kerris7: good morning!

7:32 rhickey: hi

7:33 Chouser: I replaced a couple (dosync (commute ...))s with (swap! ...)s last night

7:33 Kerris7: I've been writing 90% of my Java homework using (tail) recursion and constructive instead of destructive updates :V

7:33 Chouser: it took me a while to realize I was relying on the return value of the dosync

7:33 Kerris7: excellent!

7:33 rhickey: ah

7:33 Kerris7: this functional paradigm is catching

7:35 Chouser: Kerris7: have to be careful of those stack overflows in Java, though, no?

7:35 Kerris7: yeah, been running into a lot of those lately

7:36 rhickey: java -Xss

7:37 Chouser: so now have (do (swap! foo ...) @foo)

7:37 rhickey: CL programmers just set a stack appropriate for their data

7:37 Chouser: seriously? amazing.

7:38 rhickey: Chouser: yeah, I held off on returning val just to give myself some more time to think about it

7:38 Chouser: atom's nice and fast, though.

7:38 rhickey: sure. Don't rush on my account.

7:38 rhickey: I think atom is an important addition

7:39 fits in the reference model nicely

7:40 Chouser: yep. I simply replaced 'ref' with 'atom' and then made the 'set!' substitiution. Everything else used @ already -- very simple change.

7:46 rhickey: people were having to use refs for truly isolated things like memoization caches, which is overkill

7:49 svn 1143: swap! returns new value

7:55 hoeck: are there some more docs on atom and swap (besides (doc ..))?

7:55 chavo_: /

7:57 rhickey: hoeck: not yet

7:57 do you have a question on them?

7:58 Chouser: rhickey: yes, that was exactly my case here. my little prime stream seems to be about twice as fast with atom vs ref/dosync

7:58 clojurebot: svn rev 1143; swap! returns new value

7:58 rhickey: Chouser: wow - that's a testament to dosync

7:59 hoeck: rhickey: what are their use cases, where do they replace a ref?

8:00 rhickey: anyway, the decision shouldn't be about perf, but independence. There's no way to coordinate changes to atoms, so they better be independent forever. refs are for coordinated change

8:01 hoeck: if you imagine a grid with independent/coordinated axis and async/sync on the other...

8:02 agents: independent + async

8:02 refs: coordinated + sync

8:02 atoms: independent + sync

8:02 and coordinated + async makes no sense

8:03 lisppaste8: cemerick pasted "loop destructuring happening in recur's lexical scope?" at http://paste.lisp.org/display/71571

8:03 * hoeck draws on paper

8:03 clojurebot: svn rev 1144; made APersistenVector.compareTo use Util.compare on elements

8:06 rhickey: cemerick: binding is not lexical scope

8:07 hoeck: rhickey: thanks!

8:07 cemerick: rhickey: well, within a single thread it is, no?

8:07 rhickey: no, it's dynamic scope

8:07 cemerick: I didn't actually consider this an issue with binding, but with the destructuring of loop happening in recur

8:08 rhickey: you'll have to show me a problem not involving binding

8:09 AWizzArd: Btw, atom is not yet in the api description on clojure.org right? What is it good for?

8:09 rhickey: if you use an expression involving *blah* it means what ever the value of *blah* is at the time

8:11 cemerick: rhickey: right -- and my intuition about recur is that it pushes the arguments provided back into the in-context loop (or fn) -- in the provided example, doesn't that mean that the binding of dec to *fn* has been popped off by the time that arg gets to loop's destructuring?

8:13 AWizzArd: What is an atomic reference?

8:13 rhickey: cemerick: dynamically, no - imagine it was a tail call

8:14 (defn foo [] ... (binding ... (foo)))

8:14 cemerick: having never done any scheming, I'll have to think about that for a little while...

8:15 rhickey: ah, so effectively, recur "carries forward" the body of the loop, so each recur maintains recur's lexical scope...

8:16 rhickey: you have to stop talking about lexical scope with binding - binding is not lexical

8:16 that it's problem/benefit

8:16 lisppaste8: Chouser pasted "primes using atom" at http://paste.lisp.org/display/71572

8:17 Chouser: AWizzArd: ^ an example of atom and set!

8:17 sorry, swap!

8:17 cemerick: it's amazing how far one can get without truly understanding things!

8:17 rhickey: cemerick: :)

8:17 AWizzArd: oh, swap! is also new

8:17 cemerick: Short of recur, then, I'm unclear about how binding != let given a single thread of execution

8:18 rhickey: dynamic binding can be confusing

8:19 lvijay: so atoms are unsynchronized mutable objects?

8:19 rhickey: cemerick: because any use of a dynamic var anywhere means 'the current dynamic value', not the value at the point the code was written

8:19 AWizzArd: atom is more or less like an agent, but it runs in the same thread yes? And we don't (send) an atom, but (swap! it).

8:19 rhickey: lvijay: not at all, that is why they only support swap! - it is atomic and not subject to race conditions

8:20 but it is CAS sync, not monitor sync

8:20 lvijay: ok now i'm confused

8:20 AWizzArd: what is a cas sync?

8:20 lvijay: what is CAS synch?

8:20 rhickey: compare-and-swap

8:21 is an atomic operation

8:21 lisppaste8: cemerick annotated #71571 with "perhaps finally understanding bindings" at http://paste.lisp.org/display/71571#1

8:21 AWizzArd: compare with what?

8:21 lvijay: is the code for atom in src/clj/clojure/core.clj?

8:22 rhickey: internally swap! uses a cas spin, essentially read, make new value, try to swap it in, if when swapping it is found that the value has changed, don't replace it, try again

8:22 core_proxy.clj

8:22 AWizzArd: 10k retries?

8:22 rhickey: AWizzArd: ?

8:22 lvijay: is it like: value=atom; synchonized (lock) { if (lock == value) swap(atom, new_value); }

8:23 AWizzArd: dosync retry 10k times before they give up

8:23 lvijay: pseudo java

8:23 rhickey: AWizzArd: no retry limit

8:23 AWizzArd: You said swap! retries if it sees that the value has changed (from some other thread)

8:24 lvijay: ok, spin lock.

8:24 got it

8:24 now i look at the code

8:24 are there any example uses?

8:24 cemerick: rhickey: so, is it right to say that, conceptually, binding just set!'s the vars with the values initially provided, and then resets them to their pre-binding values upon exit?

8:24 lvijay: example code, i mean

8:25 AWizzArd: cemerick: but only for this specific thread

8:25 rhickey: cemerick: dynamically, yes, it's a stack discipline

8:25 AWizzArd: other threads still see the original binding

8:25 cemerick: right, I'm only talking about single-threaded execution here

8:26 well, that clarifies things quite a bit :-)

8:26 lvijay: ah so it uses AtomicReference

8:26 neat

8:27 rhickey: lvijay: yes, just wraps AtomicReference in Clojure abstraction, and makes easy to use, supports deref/@, validators

8:27 Chouser: lvijay: I just posted an example of atom and swap! http://paste.lisp.org/display/71572

8:28 probably the simplest possible use case

8:28 lvijay: Chouser: you call that simple???

8:29 Chouser: well, I mean the use of atom is simple.

8:29 no compare-and-set! no validator.

8:29 rhickey: memoize would probably be simplest use

8:29 no prime logic

8:30 Chouser: true.

8:30 * rhickey starts timer...

8:30 AWizzArd: for? :-)

8:30 rhickey: Chouser

8:30 to write memoize

8:30 :)

8:30 lvijay: :)

8:31 abrooks: heh.

8:31 hoeck: :)

8:31 lvijay: ok my repl just hung because of the paste

8:31 abrooks: Chouser: No pressure. :)

8:32 cemerick: I think a simple example of some code set!-ing a var within the lexical scope of a binding form would help to clarify things for any other pikers like myself who come across http://clojure.org/vars

8:32 abrooks: You know.. the problem with identifiers that allow exclamation points is that I spent a moment trying to figure out why people were so excited about swap!

8:33 lvijay: :)

8:33 cemerick: Until now, I've only thought of binding as being a handy way to thread a value across fn calls, but clearly I've not been using everything available to me.

8:33 rhickey: cemerick: the best example of the power of binding is *out*

8:34 AWizzArd: What is the main difference between atoms and agents? That atoms don't run in their own thread?

8:34 cemerick: rhickey: which I've used a good deal, but even then, it still just feels like a cross-fn let with a globally-available storage location

8:34 rhickey: although set! is interesting as a way to communicate up the stack

8:35 cemerick: I see

8:35 cemerick: I think the set! example is really what exemplifies the mechanics of what's going on

8:35 * rhickey hates to encourage set!

8:36 gnuvince: Hello

8:36 cemerick: that is the mechanism for bubbling up data from many frames down, though, right?

8:36 rhickey: cemerick: yes

8:37 lisppaste8: lvijay annotated #71572 with "this returns nil?" at http://paste.lisp.org/display/71572#1

8:39 lvijay: can someone comment on the above paste? I replaced Chouser's (iterate inc 3) with (range 1 100)

8:43 lisppaste8: rhickey pasted "memoize with atom" at http://paste.lisp.org/display/71574

8:44 lvijay: rhickey: thanks.

8:44 that was easier to understand

8:52 lisppaste8: lvijay annotated #71572 with "this works" at http://paste.lisp.org/display/71572#2

8:55 Lau_of_DK: Is anyone working on a Clojure Yansippet?

8:55 s/Yansippet/Yasnippet

8:55 AWizzArd: rhickey: if-let :-)

8:55 lisppaste8: rhickey annotated #71574 with "forgot about if-let" at http://paste.lisp.org/display/71574#1

8:55 AWizzArd: uh!

8:59 lvijay: Lau_of_DK: what's yasnippet?

8:59 Lau_of_DK: Its something that comes close to Intellisense for Emacs, speeds things up quite a bit

9:00 cemerick: are snippets at all useful in a lisp where boilerplate is slight to nonexistent?

9:00 lvijay: i was writing something like that

9:00 Lau_of_DK: http://code.google.com/p/yasnippet/

9:00 Check out the screencast

9:00 lvijay: i posted it to the groups yesterday

9:00 oh wait

9:00 intellisense

9:00 Lau_of_DK: cemerick: Somebodys who's made the attempt will have to answer that

9:00 lvijay: that's a nifty thing

9:01 cemerick: I just can't think of any repetitive code patterns I run into *shrug*

9:02 AWizzArd: how can send a thread sleeping for n milliseconds?

9:03 Lau_of_DK: cemerick: There are a few things where tab completion would speed it up, like you type map<tab> and you get (map % %) to quickly enter. Im not sure how good the idea is, thats why I asked

9:03 lvijay: (Thread/sleep n)

9:03 AWizzArd: thx

9:04 cemerick: I think the biggest wins will be sexpr navigation/editing primitives and completion of java names (in enclojure, hopefully :-))

9:05 Lau_of_DK: Javanames would be nice

9:05 lvijay: so that's what i submitted (incompletely) to the clojure group yesterday

9:05 let me see if i can find it

9:08 http://groups.google.com/group/clojure/browse_thread/thread/5595e9597e14c8b3/cce596f2aa248408

9:10 cemerick: lvijay: I'm sure ericthorsen and crew have that sort of thing on the drawing board

9:10 lvijay: that's good to know

9:10 will it help with emacs?

9:10 cemerick: the church of emacs is likely on its own ;-)

9:11 lvijay: my plan was to write this in clojure, inspect a clojure file for Java-styled symbols (camel case, starts with caps...) and build import statements where possible

9:12 emacs thru swank would use this to import files

9:12 but i got bored :)

9:12 cemerick: yeah, some standard modules to support IDE functionality are surely welcome. I know the enclojure and eclipse plugin teams have talked (at least briefly) about sharing some base functionality.

9:14 RSchulz: Good morning...

9:14 Who checked in the current clojure-contrib/trunk/build.xml?

9:14 It's broken.


9:14 /repo/JT/clojure-svn/clojure-contrib/trunk/build.xml:62: The <jar> type doesn't support the nested "path" element.

9:14 Or is my version of ant outdated?

9:15 drewolson: RSchulz: i'm fairly sure that should be classpath, but i didn't check it in :)

9:15 lvijay: RSchulz: ant works for me

9:15 i'm on svn 1144

9:15 drewolson: RSchulz: works for me too

9:16 RSchulz: Which SVN rev are you at? I just did an "svn up" this morning before the failing build.

9:16 That's the SVN for Clojure. I'm talking about Clojure-Contrib.

9:16 Rev is 273.

9:16 drewolson: RSchulz: 273

9:16 lvijay: sorry, i missed that bit. i'm on some old clojure-contrib

9:16 RSchulz: Which version of ant are you using?

9:16 drewolson: 1.7.1

9:17 RSchulz: I'm using 1.6.2

9:17 drewolson: hrm, that might be the issue

9:17 RSchulz: Time to upgrade, I guess...

9:18 lvijay: RSchulz: since ant 1.6.2 The nested indexjars element specifies a PATH like structure. Its content is completely ignored unless you set the index attribute of the task to true.

9:18 http://ant.apache.org/manual/CoreTasks/jar.html

9:19 RSchulz: Ha. Somewhere along the line, I already downloaded the tarball!

9:25 OK. That was it. Sorry for the noise.

9:44 Chouser: I was going for classy, but I think I ended up with cheesy: http://clojure.googlegroups.com/web/clojure-conc.png

9:44 oh well. there's the concurrency graph that rich described.

9:45 rhickey: typo: s.b. independent

9:46 colorful!

9:47 cemerick: it's very SICP-esque :-)

9:50 Chouser: fixed, thanks.

9:50 gnuvince: heheh :)

9:51 Chouser: certainly not up to tomhickey standards, is it. :-P

9:51 rhickey: Chouser: thanks, I think that graph is the way to think about refs

9:51 er, references

9:52 Chouser: of course var is missing to make it a complete clojure-supported-mutable chart. We might have to go 3d for that.

9:53 rhickey: Chouser: the other D is shared/isolated, complicated by the shared root bindings of vars

9:53 Chouser: if they were forced into that chart, I guess Var would be synchronous/independent?

9:54 gnuvince: What does atom do?

9:54 Chouser: gnuvince: doesn't the chart answer your question?

9:54 :-)

9:55 gnuvince: Chouser: I guess I don't see why independent data needs to be synchronized

9:56 Chouser: it can be independent of other state, but still shared by multiple threads.

9:57 In C: x = x + 1 has a race condition, even if x is independent of any other state

9:58 ref and dosync can do the job, but that's more work than needed if not coordinating multiple refs.

9:58 so atom provides a thread-safe mutable solution for a piece of state that stands alone.

9:59 gnuvince: more work for the programmer or more work for the run-time?

9:59 Chouser: both

9:59 (dosync (alter x inc)) becomes (swap! x inc)

10:00 ...and the runtime has to do much less work.

10:00 gnuvince: ok

10:05 rhickey: Chouser: the graph you have is the shared plane, the isolated plane would have only var in sync/independent, but the async/coordinated flavors make no sense in that plane anyway

10:07 Chouser: yeah, ok. async within a single thread -- I guess not.

11:04 hm! I only just now noticed that def doesn't support destructuring.

11:08 danlarkin: how would it? (def [a b] [1 2])?

11:10 Chouser: why not?

11:20 danlarkin: not saying it shouldn't

11:32 but it could only destructure as a vector? how would a map work

11:32 AWizzArd: danlarkin: same as everywhere else

11:33 drewolson: is there an easy way to turn ([1 2] [3 4]) into {1 2 3 4}

11:34 rhickey: drewolson: (into {} [[1 2] [3 4]])

11:35 AWizzArd: (let [{val1 :key1, val2 :key2} {:hallo 10 :key1 30 :key2 40 :x :y}] ...)

11:36 Chouser: danlarkin: for the record, I'm not saying it should, I was just surprised to notice it didn't.

11:36 AWizzArd: danlarkin: check also http://clojure.org/special_forms#toc4

11:36 Chouser: I've never wanted it before, and even in the case where I just thought of it it would have been a poor choice.

11:36 AWizzArd: Yeah, I also thought that destructuring works everywhere, where bindings are made

11:37 Chouser: you basically wanted something like (in Python) a, b, c = 10, 20, 30

11:37 Chouser: AWizzArd: yes

11:38 The reason I didn't want them separate is I wanted them to share a lexical scope.

11:38 AWizzArd: is it for def's not always the global scope?

11:39 Chouser: (def [a b] (let [x ... y ...] [(fn f1 ...) (fn f2 ...)]))

11:39 this would create global 'a' and 'b' that each closed over the same 'x' and 'y'

11:44 dthomas: Can you not turn that inside out? (let ... (defn ...) (defn ...))?

11:45 Chouser: yeah, I guess that would be okay. def's anywhere other than the top level scare me.

11:45 well, not scare -- make me uncomfortable.

11:49 drewolson: rhickey: thanks

11:50 AWizzArd: sure, one can work around this of course

11:50 destructuring nothing but syntactic sugar

11:50 +is

12:21 hiredman: clojurebot: latest?

12:21 clojurebot: latest is 1144

12:34 danlarkin: clojurebot: you're so rad

12:34 clojurebot: I don't understand.

12:34 danlarkin: you wouldn't... :-/

12:43 RSchulz: Does clojurebot have to be told the latest SVN rev?

12:51 duck1123: RSchulz: I think it automatically updates that value, but if you tell it the latest is something else, it will announce back up to the latest

12:51 RSchulz: Spiffy

12:57 technomancy: RSchulz: yeah, he polls it every five minutes.

12:57 clojurebot: latest?

12:57 clojurebot: latest is 1144

12:57 RSchulz: So clojurebot _is_ a he, eh?

12:57 technomancy: heh... officially an it, but I can't keep things straight.

12:58 duck1123: I think the general consensus has been to refer to it as male

14:19 hiredman: clojurebot: alter is <reply>no, you mean commute

14:19 clojurebot: You don't have to tell me twice.

14:19 Roger.

14:20 hiredman: uh oh

14:20 ozy`: clojurebot: info

14:20 clojurebot: It's greek to me.

14:20 ozy`: clojurebot: stats

14:20 clojurebot: excusez-moi

14:21 * ozy` schemes

14:21 hiredman: ugh

14:22 side effects in my transactions

14:28 Chouser: the only high-order functions that provide any state from previous iterations are reduce and iterate, right?

14:29 rhickey: Chouser: I think so

14:30 Chouser: and of those only iterate can produce a lazy sequence

14:31 I probably should just use lazy-cons

14:32 AWizzArd: How can I select (filter) every nth element of an collection into a new one?

14:33 Chouser: AWizzArd: take-nth

14:33 which is essentially a special case of partition

14:34 rhickey: ?

14:34 AWizzArd: In the mathematical sense?

14:35 Chouser: (defn take-nth [n c] (map first (partition 1 n c)))

14:36 rhickey: that's not a case of partition

14:36 that's a use of partition

14:36 Chouser: yes, of course you're right.

14:36 I've forgotten the 'map first' detail before too.

14:37 rhickey: I thought you had some way to do take-nth with just partition :)

14:37 Chouser: I did too. :-P

14:39 rhickey: anyone planning on attending ILC 2009 in Boston this March 22-25?

14:40 and would you sit through a full day Clojure tutorial if there was one?

14:41 Kerris7: why do all the cool things happen on the other side of the pond :(

14:41 Chouser: ...and half-way across the continent.

14:42 rhickey: Kerris7: I'm speaking at QCon in London in March also

14:42 Kerris7: :O

14:43 crumbs I'll have to put that down on my timetable

14:47 rhickey: half day Clojure tutorial?

14:47 hate Boston?

14:47 Kerris7: rhickey: you'll be doing the Functional and Concurrent Programming Languages Applied track?

14:48 rhickey: Kerris7: no - Emerging languages in the enterprise - http://qconlondon.com/london-2009/tracks/show_track.jsp?trackOID=231

14:48 Kerris7: Alright, thanks.

14:49 Chouser: rhickey: can't get to Boston.

14:50 Lau_of_DK: rhickey: One thing I dont remember if you commented on before. I understood why you picked functional programming and concurrency as main focus points for clojure. But what made you settle on Lisp ?

14:50 rhickey: Lau_of_DK: Lisp is right

14:52 Lau_of_DK: So would you say its primarily an emotional decision? :)

14:53 rhickey: no

14:55 AWizzArd: Lau_of_DK: Lisp can do what the other languages also can. But on top of it, you don't write programs as strings, but instead as something like parse trees. That gives you additional control that is harder to get in other languages.

14:55 gnuvince: Lau_of_DK: small core, very extensible, code can manipulate code

14:56 ozy`: Lau_of_DK: plus the parentheses look really neat

14:56 gnuvince: Lau_of_DK: the alternatives are slim

14:56 Kerris7: the QCon registration fees are impressive .__.

14:56 ozy`: (if you're going to do functional programming but you don't want to do lisp, the alternatives are basically ML and Haskell)

14:56 AWizzArd: The parens are there mostly because we have functions that take any number of args, and to make writing macros easier.

14:56 Chouser: Lau_of_DK: you could propose specific alternatives for us to shoot down. :-)

14:56 AWizzArd: ozy`: Erlang and F#

14:57 Lau_of_DK: gnuvince, AWizzArd, thanks good points

14:57 ozy`: AWizzArd: you're right, there's Erlang. F# is basically ML though

14:57 Lau_of_DK: But Im really interesting in what you mean rhickey, when you say that Lisp is right, what do you base that on ?

14:57 Chouser: Ive always been fond of the x86 Assembler language, its very concise and clean of misunderstandings and bloat

14:58 gnuvince: Lau_of_DK: the design has been pretty stable for 50 years and (most) other languages still don't have the capabilities that Lisp can provide.

14:58 rhickey: among other things, code is data

14:58 or should be

14:58 AWizzArd: Lau: you just got the reasons what makes Lisp special. Usually it takes most people several years to understand this.

14:58 Chouser: Lau_of_DK: lisp allows you to add new language primitives. Assembly does not. Next?

14:59 Lau_of_DK: AWizzArd: I know and Im familiar with Lisp and its history, so when I ask Rich its because I was interesting in his view on the subject specifically. Not because I dont have my own oppinion.

14:59 Chouser: HAHA

14:59 Chouser: I think C# coupled with Visual Studio provides awesome development speeds.

15:00 Chouser: Lau_of_DK: lisp allows you to add new language primitives. C# does not. Next?

15:00 :-)

15:00 AWizzArd: Lau_of_DK: after Rich said it was not an emotional descision it means it must be something that Lisp has and most languages don't. So, the question was implicitly answered by then.

15:00 Lau: it is not C#, but the libraries of .NET.

15:00 Lau_of_DK: AWizzArd: Thanks alot

15:01 AWizzArd: Reusing code is the productivity boost number 1.

15:01 Lau_of_DK: AWizzArd: wrong, Emacs is always #1

15:01 AWizzArd: If you just need to say (foo 1 2) instead of writing 10-2000 LOC you are more productive.

15:02 Chousuke: basing a language on lisp also lets you not worry that much about what the syntax will be like, because it's extensible. After all, every decision you have to make limits what the programmer can (easily) do.

15:02 rhickey: Syntax is generally language fail

15:02 AWizzArd: C# does not offer anything important that Lisp doesn't. So in general you can't outperform Lisp with C#, language wise.

15:03 As soon libs come in the game is different. But Rich solved this problem, by giving Clojure all jvm libs.

15:03 Lau_of_DK: I said C# coupled with Visual Studio

15:03 AWizzArd: An IDE can help.

15:03 rhickey: BTW, I did not say only Lisp is right

15:03 But C# is definitely wrong

15:04 :)

15:04 Lau_of_DK: <rhickey> Lau_of_DK: Lisp is right

15:04 Kerris7: I just like the way how functional languages tend to encourage people to think before coding, rather than spending time sifting through APIs</anecdotal evidence>

15:04 AWizzArd: But currently the AI in VS is smaller than the natural intelligence of most humans. So, VS won't help too much.

15:04 As soon Visual Studio becomes about as intelligent as humans, then languages won't matter any longer.

15:04 Chousuke: Lau_of_DK: if C# with an IDE is nice, try to imagine clojure with an equally good IDE. :p

15:05 Lau_of_DK: AWizzArd: When was the last time you tried VS?

15:05 The intellisense there is insane nowadays

15:05 Chousuke: I am trying... hard :)

15:05 My Emacs is almost up to speed now :)

15:05 AWizzArd: Lau: x = a+8; how can the ide help me here?

15:05 I wanted to say x = a+9

15:05 Lau_of_DK: AWizzArd: I think you need to go to #newbies to have that answered :)

15:06 AWizzArd: No Lau, the IDE can't understand humans and their intentions. It does all it do mechanically, without any thinking involved.

15:06 And lot's of stuff that IDEs can do are not needed in Lisp anymore.

15:07 leadnose: speaking about intentions, i found this a rather nice read: http://www.technologyreview.com/computing/18047/page1/

15:07 AWizzArd: The ide has to provide this stuff, because otherwise languages like C# and Java would be impossible to write programs in.

15:09 Kerris7: Chousuke: do you use enclojure?

15:09 AWizzArd: What do we need setters/getters for in Clojure? It is nice that an IDE can insert the code for them, but they are useless.

15:10 Chousuke: Kerris7: no

15:10 AWizzArd: The wizards, that insert good bits of code are basically trying to simulate what macros do in Lisp.

15:10 Chousuke: Kerris7: just SLIME

15:10 gnuvince: rhickey: are there other languages that you find "right"?

15:10 Chousuke: AWizzArd: heh. macros are more readable too

15:11 Lau_of_DK: AWizzArd: I disagree

15:11 Chousuke: AWizzArd: mostly because there's less to read.

15:11 AWizzArd: Lau: with a few more years of Lisp experience you wouldn't, so let's talk in 2011 again

15:12 Chouser: gnuvince: if there were, I imagine he'd be using them instead of creating Clojure :-)

15:12 Lau_of_DK: AWizzArd: Actually it might be you who need a little experience, but only time well tell

15:13 rhickey: gnuvince: compromises abound. Haskell has its own conceptual rightness, but is syntactically wrong

15:13 Chousuke: Lau_of_DK: IDE code generation is basically manually copy-pasting expanded macros into your code :/

15:14 kib2: rhickey: why do you think Haskell is syntactically wrong ?

15:14 Chousuke: if you wanted to make some stuff expand differently after a while, that's impossible to do with generated code. You'll have to rewrite all expansions manually :/

15:14 gnuvince: kib2: probably because the syntax cannot be manipulated

15:15 Chouser: there can be others which are just not his cup of tea. I find Factor interesting for example, but don't see me writing code with anytime soon

15:15 leadnose: there is always template haskell and liskell :)

15:16 rhickey: leadnose: I definitely need to check out Liskell - does it come with a translator that turns ordinary Haskell into sexprs?

15:16 kib2: gnuvince: right, but I've heard of a project to handle sort of macros in haskell

15:17 leadnose: I haven't actually tried it, just seems a neat idea with the type checking of haskell and flexibility of lisp and macros

15:17 gnuvince: kib2: TemplateHaskell. It's possible, but it's definitly a whole lot messier than Lisp

15:17 kib2: gnuvince: that's it !

15:17 AWizzArd: TemplateHaskell only showes that some Haskell coders think that something is missing with the Haskell syntax.

15:18 rhickey: haskell simply does too much with adjacency, you constantly have to parse, apply precedence etc. currying is too subtle

15:18 kib2: There's another interesting language : factor. It has macros, seems really powerfull but lacks docs.

15:18 gnuvince: kib2: there's a guy writing a tutorial that's pretty good

15:18 http://elasticdog.com/2008/11/beginning-factor-introduction/

15:19 leadnose: I've found that haskell is sometimes kind of hard to read, it requires lot's of good taste to know how to write it neatly

15:19 gnuvince: Very interesting language, very smart creator, but I have problems designing a solution with stacks

15:19 kib2: gnuvince: nice, thanks a lot.

15:19 hiredman: clojurebot: what is the latest revision?

15:19 clojurebot: what is the latest revision is 1144

15:19 rhickey: yeah, I just can't think that (stack) way all the time

15:19 danlarkin: postfix syntax makes me think of the computer lab from university in which we had to write projects in postscript... bad memories

15:19 hiredman: hmm

15:20 gnuvince: I once tried to write map in Factor

15:20 kib2: gnuvince: I totally agree

15:20 technomancy: did factor move off or on to the JVM?

15:20 gnuvince: It's a piece of cake in any applicative language; in Factor, it was very hard.

15:20 kib2: technomancy: off

15:20 gnuvince: technomancy: it was implemented in Java originally, it's now only in C.

15:20 technomancy: ah, interesting

15:20 gnuvince: The Java version isn't supported anymore.

15:25 Lau_of_DK: gnuvince: why this fascination with stack ?

15:27 gnuvince: Lau_of_DK: my fascination or in general?

15:28 Lau_of_DK: in general, what do these guys seek to accomplish with this focus on stack ?

15:28 gnuvince: Lau_of_DK: it's another way to organize a program, and it has some advantages over applicative languages.

15:29 Lau_of_DK: How so?

15:31 gnuvince: For instance, you read it from left-to-right instead of inner-to-outer. It's easy to return multiple values, just push them onto the stack. It also makes combining words (functions) that return multiple values and consume multiple values easier.

15:32 notallama: meddling with continuations seems like it'd be trivial.

15:32 Lau_of_DK: Thanks gnuvince

15:32 kib2: Lau_of_DK: stack is a simple concept, but you can make really beautiful things with it, ie look at the Postscript language

15:32 Lau_of_DK: I'll have a look see

15:33 Chousuke: hm

15:33 gnuvince: Lau_of_DK: look at the elasticdog posts on Factor

15:33 Lau_of_DK: I read it

15:33 notallama: in my c class, my assignments generally have to produce postscript as output. i quite like it. most of my class does not.

15:33 gnuvince: Lau_of_DK: ok

15:34 Lau_of_DK: gnuvince: To me, it just looks like a dumb way to work with data, forcing a complexity on you which the language should actually remove

15:37 gnuvince: I wouldn't call it dumb, although I would agree that it imposes a cognitive load on the programmer that we could do without.

15:38 danlarkin: Oh jeez... just ran the numbers on this calculation I'm doing. At the current rate it'll finish in 6 years :-o Time to refactor

15:38 gnuvince: danlarkin: what calculation is that?

15:38 Lau_of_DK: gnuvince: ok, what if we do this (def dumb "force a cognitive load on a programmer")

15:38 Would you say its dumb then ?

15:38 :)

15:38 Chousuke: all languages do that to an extent :P

15:39 Lau_of_DK: hehe

15:39 danlarkin: gnuvince: something for work, 191 million calculations + store to the DB

15:40 gnuvince: danlarkin: heh :)

15:40 nsinghal: I have a vector (def v [4 5 6 7]) what is the function to remove value 6 from the vector?

15:40 Lau_of_DK: filter?

15:40 danlarkin: gnuvince: and my boss thought this was going to be nightly cronjob :)

15:40 Lau_of_DK: (doc filter)

15:40 clojurebot: Returns a lazy seq of the items in coll for which (pred item) returns true. pred must be free of side-effects.; arglists ([pred coll])

15:40 gnuvince: Lau_of_DK: I wouldn't do this in the first place, I'd use a more appropriate var name ;)

15:40 Chouser: nsinghal: vectors only grow/shrink effeciently on the right-end

15:41 gnuvince: danlarkin: are you under a strict NDA, or can you tell us what these calculations are?

15:41 Chouser: (remove #{6} [4 5 6 7]) ==> (4 5 7) ...but that returns a seq

15:42 nsinghal: you can wrap it in (vec ...) to build a new vector from the results, but that's O(n)

15:43 nsinghal: i probably use map where i am using vector - that list will really be changing frequently

15:43 notallama: a c style language force a load on programmers and compilers without much of any benefit. a stack language puts a load on humans, but very little on the computer, so it allows you to reason about what parts of the code generation you can automate, much like a lisp, but with some differences.

15:44 Chouser: nsinghal: 'remove' returns a lazy seq, which should work nicely if you're passing in a lazy seq from 'map'

15:45 danlarkin: gnuvince: can't really say much, just a domain-specific algorithm designed by the client. At least it can be written as a pure function and easily parallelized

15:45 gnuvince: danlarkin: ok

15:46 nsinghal: Chouser - thx i will try to change my vector and use other data structure

15:46 Chouser: nsinghal: if you're doing a lot off adding/removing from the middle you might like a hash-set or sorted-set

15:47 Lau_of_DK: Does anyone else wonder a little about CGrandes latest blogpost/ understand why it is so ?

15:47 nsinghal: i will read up on hash-set and sorted-set - never used them

15:57 kib2: I just buy "Programming with Clojure". Hoping it's a good book.

15:57 technomancy: it is

15:57 kib2: technomancy: thanks

16:06 AWizzArd: http://pragprog.com/podcasts/show/24

16:08 RSchulz: kib2: The book is definitely good, even though it's just beta 3, right now. And you can find the author here and on the Clojure Google Group / mailing list.

16:08 kib2: whaoo...my old "clojure.jar" was 1.18 Mo, it's now 1.80 Mo : I should have missed a lot of new things !

16:09 RSchulz: yes, from what I'm currently reading, it misses some chapters, but the first 5 are here :)

16:09 RSchulz: Stuart expects the next beta fairly soon.

16:09 He knows we're chomping at the bit.

16:09 danlarkin: kib2: what's an Mo?

16:10 RSchulz: Megabyte

16:10 In French...

16:10 danlarkin: ah

16:10 RSchulz: Megaoctet

16:10 danlarkin: I see

16:10 kib2: danlarkin: MegaOctet

16:12 danlarkin: octet makes a lot more sense than byte

16:13 RSchulz: Especially since there are computers out there with, say, 10-bit bytes.

16:13 Univac is 36-bit word, 9-bit byte.

16:13 notallama: it also sounds cooler.

16:13 RSchulz: I don't know if they're still made, though.

16:13 We had one back in school.

16:14 Batch mode. Card readers. Very old-school.

16:14 And there are nybbles, too: 4 bits.

16:18 danlarkin: we read about univacs in history books in school :)

16:23 kib2: is someone here using a Win XP os with Clojure ? I've got problems in setting my CLASSPATH correctly (from the book)

16:23 mehrheit: danlarkin: is that an emacs variant?

16:24 Chouser: I don't think there's currently a foo such that (foo + [1 2 3 4 5]) ==> (3 6 10 15), right?

16:24 danlarkin: mehrheit: ha! http://en.wikipedia.org/wiki/UNIVAC_I

16:24 RSchulz: kib2: Are you using Windows-style CLASSPATH syntax? Semicolon separators, in particular?

16:24 kib2: RSchulz: yes

16:24 RSchulz: What symptom are you getting?

16:25 mehrheit: danlarkin: well, the plural sounds similar

16:26 kib2: RSchulz: "could not find the main class : clojure.lang.Repl"

16:26 RSchulz: mehrheit: Univac is a mainframe computer from the 70s and before.

16:26 rhickey: Chouser: no

16:26 RSchulz: (or maybe _was_)

16:26 How sure are you that your CLASSPATH is correct?

16:26 And are you sure it's established as an environment variable?

16:27 Are you using CMD.exe or Cygwin?

16:27 kib2: The book told me to make a bat file with "SET CLASSPATH=/jars/clojure.jar;/jars/clojure-contrib.jar;etc." but what is "/jars" supposed to be ?

16:27 Chouser: rhickey: ok, thanks.

16:27 kib2: RSchulz: CMD.exe (via Console2)

16:27 rhickey: Chouser: http://www.zvon.org/other/haskell/Outputprelude/scanl_f.html

16:28 RSchulz: That's just an example You have to use the actual drive letter and directory in which you have your Clojure JAR file.

16:28 I strongly recommend Cygwin for programmers using Windows.

16:29 notallama: windows powershell looks like it's fairly non-horrible too.

16:29 kib2: RSchulz: sure, that's what I've did but it does not work.

16:29 Chouser: rhickey: excellent, thanks.

16:29 RSchulz: Check by taking the file names from the CLASSPATH and checking that you can access them by that name.

16:30 rhickey: Chouser: deja vu: http://paste.lisp.org/display/68046#2

16:30 notallama: kib2: does it work with the -cp flag, instead of setting the global classpath?

16:30 Chouser: sheesh

16:31 RSchulz: It should.

16:32 hiredman: clojurebot: scanl is http://paste.lisp.org/display/68046#2

16:32 clojurebot: Ok.

16:33 hiredman: stupid functional programming stuffs being so useful

16:33 Chouser: that inits thing you mentioned yesterday is now used in clojurebot for fuzzy matching stuff

16:33 the doc string for the inits function says "this is chouser's fault"

16:34 Chouser: hiredman: gah. I can't remember a thing. Did I post an implementation or something?

16:35 hiredman: you were looking for inits, then remembered you had looked for it before

16:35 then pasted a url for irc logs, where you had pasted a link to an implementation

16:35 Chouser: oh, right. but it was my implementation, not rhickey's. I coulda sworn he wrote a better one...

16:36 hiredman: clojurebot: please pontificate on the subject of multimethods

16:36 clojurebot: multimethods is what separates the boy from the man.

16:37 RSchulz: Maybe you need some pithy noun-oriented vs. verb-oriented programming aphorism in there...

16:37 lisppaste8: kib2 pasted "batch file" at http://paste.lisp.org/display/71603

16:37 * technomancy just found some mutable state in his test suite that took two days to track down.

16:38 technomancy: man... the next time I do anything like that I'm flagging it with huge FIXME/HACK comments.

16:38 kib2: I've now got the REPL, but typing "(require :verbose 'clojure.contrib.str-utils)" raise an error

16:38 RSchulz: Some of the nastiest bugs I've written have been in "mostly immutable" data structures. That 1% mutability can kill you...

16:39 technomancy: RSchulz: actually this is not a clojure project, it's just a project that would be way simpler in clojure.

16:39 hiredman: kib2: you don't have clojure.contrib in the cp

16:39 technomancy: this is my jruby stuff from work

16:39 RSchulz: And the bugs I mentioned were in Java code. (Of course.)

16:39 technomancy: heh

16:39 hiredman: -cp %CLASSPATH%;%CLOJURE_DIR%

16:39 technomancy: the worst is when the problem is in your test fixtures and you think it's in the implementation

16:39 hiredman: and you are playing pretty fast and loose with / v. \

16:39 kib2: hiredman: I've got a line "set CLASSPATH=%CLOJURE_DIR%\clojure-contrib.jar"

16:40 hiredman: kib2: yeah, well, that is being ignored for whatever reason

16:41 RSchulz: You might try sticking an "echo" in front of the Java invocation so you can see precisely what's being passed.

16:41 hiredman: clojurebot: how can I have a "jar directory" where I can put all my libs and have java pick them up?

16:41 clojurebot: a is b

16:42 RSchulz: Don't let an objectivist hear you say that.

16:42 hiredman: curse you fuzzy matching

16:42 clojurebot: how can I have a "jar directory" where I can put all my libs and have java pick them up?

16:42 clojurebot: a is b

16:42 RSchulz: Is clojurebot speaking without being spoken to?

16:42 hiredman: hmmm

16:42 no

16:43 RSchulz: Oh. There it is.

16:43 hiredman: clojurebot: how can I have some "jar directory" where I can put all my libs and have java pick them up?

16:43 clojurebot: jar directory is -Djava.ext.dirs=$LIBS

16:43 kib2: hiredman: "cp %CLASSPATH%;%CLOJURE_DIR%" --> my system tells me it needs more arguments

16:43 hiredman: so the fuzzy matching needs tuning

16:44 ozy`: hint for people using clojure on a mac: put the jar in /Library/Java/Extensions

16:44 RSchulz: kib2: Is that an invocation of "cp"?

16:44 kib2: RSchulz: yes

16:44 hiredman: kib2: just do "java -Djava.ext.dirs=%CLOJURE_DIR%" and forget about your classpath

16:45 RSchulz: Well, you need to give individual names, not PATH-like syntax and a destination, of course.

16:46 hiredman: RSchulz: the java.ext.dirs= thing works with a directory

16:46 and you just dump your jars in there

16:46 RSchulz: Yes, that's handy.

16:47 Is there a provision for multiple directories using -Djava.ext.dirs? Comma-separated list, maybe?

16:47 hiredman: I think that is correct

16:47 RSchulz: Or maybe the local platform's native PATH-style syntax?

16:48 hiredman: colon seperated

16:48 RSchulz: But colon-separated would be a big problem on Windows!

16:49 lisppaste8: kib2 annotated #71603 with "fixed" at http://paste.lisp.org/display/71603#1

16:49 kib2: Finally got it ! :)

16:52 RSchulz: The answer is here: http://java.sun.com/j2se/1.4.2/docs/guide/extensions/spec.html

16:52 It is indeed the platform-specific PATH separator.

16:53 kib2: What was amiss?

16:57 hiredman: ugh

16:57 * hiredman kills java

16:58 RSchulz: You can't kill Java. It's immortal.

16:58 technomancy: that or undead.

16:58 kib2: RSchulz: I don't know really. I've "set CLOJURE_CONTRIB=" then "java -cp %CLOJURE_CONTRIB%;%CLOJURE_JAR% clojure.lang.Script %1" and it works

16:59 technomancy: RSchulz: the two are easily confused

16:59 RSchulz: technomancy: Yeah. It's as likley the latter.

17:00 Well, we need the JVM, after all.

17:00 technomancy: right. I've aliased "java" to "jvm" in my shell just to avoid confusion between the runtime and the language

17:09 hiredman: ugh, one of the first things I wrote in clojure was a xmpp repl bot, and I am revisting xmpp, but now the smack library just wants to sit there and throw exceptions

17:43 olgen: hi, i have a small problem with namespaces in my clojure installation

17:43 i downloaded the svn version (rev. 1144)

17:44 i have a problem getting access to the names in the clojure namespce

17:44 which boils down to:

17:45 Dingo:~/local/clojure/trunk jacobm$ java -cp clojure.jar clojure.lang.Repl

17:45 Clojure

17:45 user=> (clojure/refer 'clojure)

17:45 java.lang.Exception: No such namespace: clojure (NO_SOURCE_FILE:1)

17:45 user=>

17:45 anyone knows what i am doing wrong?

17:46 danlarkin: clojure.core

17:46 hiredman: clojure is now clojure.core

17:48 olgen: user=> (clojure/refer 'clojure.core)

17:48 java.lang.Exception: No such namespace: clojure (NO_SOURCE_FILE:7)

17:48 i guess thats not what i should do?

17:50 dudleyf: olgen: No, clojure.core is already 'refer'ed for you

17:51 olgen: yes it works in the repl, but when i try working in my own namespace, i loose access to the clojure functions in the clojure.core namespace

17:51 i read somewhere that i then had to (clojure/refer 'clojure) after the (in-ns 'mynamespace)

17:51 dudleyf: olgen: If you're creating a new namespace, you should use the ns macro

17:52 (doc ns)

17:52 clojurebot: Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, defaults to :name corresponding to th

17:52 olgen: oki thanks

17:52 dudleyf: The clojure/refer stuff is out of date

17:52 olgen: ok

17:54 dudleyf: olgen: BTW, the refer function is clojure.core/refer now

17:55 namespace/name

17:55 olgen: oki, thanks for the help guys

17:55 dudleyf: np

18:07 kib2: good night, thanks for all

18:38 technomancy: does the clojure-mode author hang out in here?

18:39 dudleyf: technomancy: Not that I know of

19:26 hiredman: clojurebot: well?

19:26 clojurebot: Excuse me?

19:27 danlarkin: clojurebot: get your act together

19:27 clojurebot: Gabh mo leithsc�al?

19:31 svn rev 1145; made RT.DEFAULT_COMPARATOR use Util.compare

19:33 duck1123: did clojurebot just die?

19:33 I have my parts hidden

19:39 RSchulz: clojurebot: how many things do you know?

19:39 clojurebot: Excuse me?

19:39 RSchulz: clojurebot: what do you know?

19:39 clojurebot: It's greek to me.

19:39 RSchulz: clojurebot: how much do you know?

19:39 clojurebot: I know 80 things

19:39 hiredman: clojurebot: latest?

19:39 clojurebot: latest is 1145

19:39 technomancy: sounds like he's suffered a blow to the head

19:39 RSchulz: I think clojurebot's alive and ... speaking.

19:46 clojurebot: svn rev 1145; made RT.DEFAULT_COMPARATOR use Util.compare

19:46 hiredman: clojurebot: now keep doing that

19:46 clojurebot: Excuse me?

19:51 svn rev 1145; made RT.DEFAULT_COMPARATOR use Util.compare

19:53 hiredman: uh

20:02 danlarkin: every 5 minutes?

20:02 :)

20:03 oh, nevermind I guess that was over 5 minutes ago

20:11 * duck1123 is watching lecture 1a of SICP

20:12 gnuvince_: Those videos are awesome :)

20:12 duck1123: took a while to download

20:13 the direct download was faster than the torrent

20:19 RSchulz: Watching? Lectures?? SICP??? Where do I find these lectures?

20:20 danlarkin: *ditto*

20:22 RSchulz: Perhaps this? http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/legal-info.html

20:23 Or, maybe, this: http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

20:23 Oh, NO, Mr. Wizzard!!!

20:41 danlarkin: I dig the opening music

20:46 mortis`: thos are good lectures, the book is good too

20:52 RSchulz: danlarkin: You need to check out Wendy / Walter Carlos' recordings!

20:54 Or, perhaps, more conventional recordings of Bach's music.

20:54 Bach is, of course, eternal!

20:54 danlarkin: OH I hear about him/her on NPR the other day

20:55 I can't recall on which program

20:55 RSchulz: Really? I missed that one. I have vinyl of both "Switched-On Bach" and "Switched-On Bach II" (from my high school days)

20:56 danlarkin: ever listen to p d q bach aka Peter Schickele?

20:57 RSchulz: Yeah. Once upon a time. Not lately.

20:58 danlarkin: I love his sense of humor

21:02 RSchulz: Glenn Gould once wrote of Wendy's Bach recordings (incidentally on the back of her Well Tempered Synthesizer LP), "Carlos's realization of the Fourth Brandenburg Concerto is, to put it bluntly, the finest performance of any of the Brandenburgs--live, canned, or intuited--I've ever heard."

21:03 I listened to those albums over and over. I'm glad how reverently I treated my LPs. They're probably still in good condition, though I lost track of my last turntable many years ago...

21:04 You think if Bach were reincarnated today he'd be a Lisp programmer?

21:05 danlarkin: I doubt he'd be playing music

21:06 RSchulz: Well, not as a profession.

21:07 I learned at least one two-part invention. It helped me realize that music was _not_ my future...

21:07 But music does seem to have very salient effects on young people's brains.

21:12 Chouser: rhickey: typo at http://clojure.org/atoms "needs" should be "need"

21:32 rhickey: Chouser: fixed - thanks

21:47 larrytheliquid: http://clojure.org/vars "provides 3 distinct mechanisms for doing so in a controlled manner - Vars, Refs and Agents. "

21:47 ^ should be 4 now

21:51 jeremy__: larrytheliquid: really? what's the fourth?

21:51 Chouser: jeremy__: http://clojure.org/atoms

21:52 jeremy__: ah thanks

22:15 duck1123: jhtff7

22:15 huybg7uhuy7buyughb y ihgyibgho g cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

22:17 I am sorry about that, my daughter got ahold of the computer

22:18 notallama: my frend's cat sent me a screenshot of her desktop over msn once. it was pretty fancy.

22:48 johnwayner: tomhickey: on http://clojure.org/api the section for (gensym) has "the prefix is 'G<u>'." which is causing the entire rest of the page to be underlined. Probably want &lt;u&gt;

23:29 hiredman: clojurebot: please explain map to me

23:29 clojurebot: map

23:29 hiredman: hmm

23:29 clojurebot: tell me about map

23:29 clojurebot: map

23:31 hiredman: clojurebot: tell me about map

23:31 clojurebot: map is *LAZY*

23:31 hiredman: oh

23:56 danlarkin: nice

Logging service provided by n01se.net