#clojure log - Apr 06 2009

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

1:48 jsankey: (java.io.File. "a\\b")

1:49 ,(java.io.File. "a\\b")

1:49 clojurebot: #<File a\b>

1:50 jsankey: ,(.parentFile (java.io.File. "a\\b"))

1:50 clojurebot: java.lang.IllegalArgumentException: No matching field found: parentFile for class java.io.File

4:43 kefka: I've noticed that ArrayList access seems to be slow in a Clojure REPL. Am I doing something wrong?

4:44 AWizzArd: more info please

4:44 you are using the default JVM methods, so it should not be any slower

4:44 kefka: ,(time (let [a (new ArrayList (range 10))] (doall (for [i (range 100000)] (.get a 5)))))

4:44 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: ArrayList

4:44 kefka: ,(time (let [a (new java.util.ArrayList (range 10))] (doall (for [i (range 100000)] (.get a 5)))))

4:45 It takes about 1.3 microseconds per access on my machine.

4:45 cconstantine: I've got a crazy idea; Would it make sense to read files as a lazy-seq? Each element in the sequence would be an item from the file (Something like a line, or other defined chunk). This would make reading a file in a (dosync ...) easy/fast and would allow you to use all the nice drop, drop-while, filter, etc. lazy-seq functions. Am I crazy?

4:46 kefka: I'm on a 2.6 GHz machine, so this is thousands of clock cycles

4:46 per .get

4:47 ,(time (let [a (new java.util.ArrayList (range 10))] (dorun (for [i (range 100000)] (.get a 5)))))

4:47 dorun, not doall... I think my doall might have hurt the Clojurebot

4:47 cconstantine: kefka: that returns a long list

4:47 kefka: ,(+ 3 4)

4:48 Yes, I should have been using dorun. dorun doesn't return.

4:48 Cark: ,(doc line-seq)

4:48 kefka: doall returns a huge seq

4:48 Cark: did you guys kill poor clojurebot ?

4:48 kefka: Clojurebot seems to have been killed by my huge doall. Sorry. :(

4:48 How does one get it back?

4:48 cconstantine: I get "Elapsed time: 66.048 msecs"

4:49 talk to hiredguy?

4:49 Cark: anyways constantine : have a look to line-seq

4:50 kefka: cconstantine: It takes me about 100 msec, but that seems a lot longer than it should be, for 100k ArrayList accesses.

4:50 On a 2.6 GHz machine, that's 2600 clock cycles per access

4:50 cconstantine: Cark: that is pretty close to what I was thinking of :)

4:51 Cark: yes though i'm not sure the file gets closed if you never go to the end of it

4:51 at least it should be upon GC

4:51 cconstantine: Cark: right, it would have to be wrapped in either a generator func or macro

4:51 for the file open/close

4:52 Cark: i don't know ... i think rhickey was working on something for this ...

4:52 cconstantine: kefka: no idea what's up.... I've had disapointing results timing simple counting loops (last (range 1 100000)) compared to C

4:53 Cark: you're not comparing the same thing

4:53 use loop/recur

4:53 cconstantine: I got similar timings with loop/recur

4:53 Cark: on server jvm

4:53 cconstantine: yup

4:53 Cark: did you take "warm up " into account ?

4:54 cconstantine: I'm inclined to think clojure isn't 100 times slower than C, and that I'm doing it wrong

4:54 Cark: and used unsafe maths ?

4:54 cconstantine: unsafe maths (unchecked-inc ...) didn't seem to effect speed

4:54 Chousuke: did you make sure there is no reflection?

4:54 Cark: you coerced the counter to integers ?

4:55 cconstantine: no reflection?

4:55 I started with raw numbers at the reader, and used unchecked-inc

4:56 Chousuke: well, (.get foo 5) would cause reflection without a type hint.

4:56 bind *warn-on-reflection* to true :/

4:56 cconstantine: ah, and the time-to-run was linear with the number of increments, so the there was no "warm-up" factor

4:56 ah, I've done that. I wasn't getting reflection

4:57 poor clojurebot

4:58 I dunno, the only reason I cared even a little was that a friend doing project clojure was getting answers 10/100 times faster in C than I was in clojure using the same basic algorithms

4:58 I'm not too worried; another friend is using haskell and getting similar timings to me

4:59 s/project clojure/project euler/

5:00 and our runtimes are on the order of 1-5 seconds

5:01 gnuvince: For simple problems like that, Clojure doesn't have much of a problem with performance.

5:02 cconstantine: it's ok, I beat him on code simplicity, code length, and generality of solution (his won't work for N too large)

5:03 gnuvince: He's probably not using Integer

5:04 cconstantine: He's using C, so his types are like 'int'

5:04 Cark: hum testing this i just discovered that i can't run the server jvm on my 64bit computer =/

5:04 gnuvince: cconstantine: oh, I thought he was using Haskell

5:05 cconstantine: gnuvince: ah, yes the haskell guy is using Integer

5:09 Cark: i have a deamatic increase in speed when using server jvm, and running the test several times

5:09 dramatic

5:09 lisppaste8: url?

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

5:10 cark pasted "untitled" at http://paste.lisp.org/display/78102

5:13 hiredman: ~ticker JAVA

5:13 clojurebot: No entiendo

5:13 hiredman: useless

5:14 AWizzArd: ,(doc for)

5:14 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test. (take 100 (for [x (range 100000

5:15 AWizzArd: kefka: You use dorun and not dotimes?

5:16 On my machine your (time (let [a (new java.util.ArrayList (range 10))] (dorun (for [i (range 100000)] (.get a 5))))) ==> "Elapsed time: 55.393632 msecs"

5:16 kefka: but (time (let [a (new java.util.ArrayList (range 10))] (dotimes [i 100000] (.get a 5)))) ==> "Elapsed time: 7.141131 msecs"

5:17 '(/ 100000 7.141131)

5:17 ,(/ 100000 7.141131)

5:17 clojurebot: 14003.384057791407

5:17 AWizzArd: 14000 reads per millisecond

5:17 jgracin: Hi! Could someone please help me resolving a "not releasing the head" problem. I'll paste it in a sec.

5:17 lisppaste8: jgracin pasted "Out of heap space" at http://paste.lisp.org/display/78104

5:17 AWizzArd: No wait, nonsense of course. That is lazy and was not run.

5:19 Cark: i think it gets optimized out

5:21 jgracin: is it because "lines" is a parameter which stays bound until the function exits? I guess that's it, isn't it?

5:22 mihand: hey guys! is (int (/ a b)) the idiomatic way to do truncating division ?

5:22 Chouser: mihand: quot

5:24 Cark: jgracin : when you call find-save-debug the lines parameter points to the head of the lines sequence

5:24 so you're retaining the head

5:25 jgracin: Cark: thanks! Is there any way I can deal with this? Is this what streams are for? Where are the streams?

5:26 Cark: you could change entire-log-line-seq to return a function that will return the sequence

5:26 Chouser: streams are experimental, not in trunk

5:26 Cark: and pass that as a parameter to find-saved-debug

5:26 hey hello chouser

5:27 Raynes: Hey hello hi Chouser.

5:27 Cark: I win.

5:27 Chouser: hi guys

5:27 cemerick: hey, Chouser's back, all's right with the world again! :-D

5:27 jgracin: So I can't pass infinite lazy sequences into functions because that will necessarily blow up the heap.

5:28 I mean, if they decide to make a long search through the seq.

5:28 lisppaste8: cark annotated #78104 "untitled" at http://paste.lisp.org/display/78104#1

5:28 Chouser: hm, that can't be quite right, since you can pass infinite lazy seqs to 'filter' without a problem.

5:28 Cark: try this untested change

5:28 chouser : filter probably uses recur

5:29 Chouser: no, it's lazy. uses lazy-seq

5:29 Cark: ~def filter

5:29 well then it returns immediately

5:29 jgracin: my entire-log-lines-seq uses concat which I counted on using lazy-seq internally.

5:31 Chouser: that should be ok (though mapcat would be more succinct)

5:32 Cark: jgracin : try my solution and tell us how it goes !

5:35 jgracin: Cark: yup, it works. Thanks! I do understand how and why. It's just that it doesn't seem quite elegant. Does the streams address this kind of problem or are they for different purposes?

5:35 Cark: yes they do

5:35 hum there is another way

5:35 you could build your own filtered lazy sequence

5:35 ~def filter

5:36 Chouser: are locals cleared out before tail calls?

5:38 lisppaste8: cark annotated #78104 "untitled" at http://paste.lisp.org/display/78104#2

5:39 Cark: not sure if that will do it

5:41 chouser : my guess would be that the pointers are overwritten

5:41 so no more reference, so garbage collectable

5:48 Chouser: yes, that appears to be the case. if so, then just moving the call to 'first' out of find-saved-debug might do it

5:48 oh

5:48 like Cark's second annotation.

5:48 :-)

5:48 Cark: =)

5:49 jgracin: thanks!

5:49 Chouser: except saved-debugs is still a fn that needs to be called with the right args, but that's the gist I was headed for.

5:49 oh, nm.

6:06 Mec: is there an opposite of slurp that writes a string to a file?

6:07 dliebke: ,(doc clojure.contrib.duck-streams/spit)

6:07 clojurebot: java.lang.Exception: Unable to resolve var: clojure.contrib.duck-streams/spit in this context

6:08 dliebke: clojure.contrib.duck-streams/spit writes a string to a file

6:09 Mec: thanks

6:10 hmm class not found exception

6:10 Cark: ,(use 'clojure.contrib.duck-streams)

6:10 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/duck_streams__init.class or clojure/contrib/duck_streams.clj on classpath:

6:10 Cark: works on my machine !

6:11 Mec: yup i got it now

6:11 will spit overwrite the file?

6:13 dliebke: yes, it appears to overwrite the file

6:14 Mec: excellent, thanks

6:24 hiredman: ~ticker JAVA

6:24 clojurebot: Pardon?

6:24 hiredman: clojurebot: are you for real?

6:24 clojurebot: for is not a loop

6:26 cconstantine: ok, so it turns out I'm not using a java server

6:26 is there a place that talks about how to do that?

6:28 nm, I needed to ask the question for me to answer it myself

6:31 hiredman: ~ticker JAVA

6:31 clojurebot: JAVA; -1.98

6:38 cemerick: is it true that there's no way to determine how many arguments a fn can accept?

6:39 Chouser: you can call it with n args, and if you get an exception then it doesn't except that many.

6:39 or of those types.

6:39 or something else is wrong.

6:39 hiredman: cemerick: it is true

6:39 cemerick: so if I pull a fish out of a random hole, I get to keep the fish? ;-)

6:40 Chouser: you can look at the :arglists metadata of a var

6:40 but that can be overwritten by the user, so ... *shrug*

6:40 hiredman: Chouser is trying to sugar coat it for you

6:41 Chouser: you can do what the 'source' macro does to find the clojure source for the fn, use 'read' and 'macroexpand' and analyze the results...

6:42 cemerick: I think I'd just make a macro that attaches arity metadata :-)

6:43 but wow, dropping to the source macro is imaginative...

6:43 Chouser: but so very very wrong

6:44 hiredman: Fn objects don't let you attach metadata

6:44 cemerick: ah, damn

6:44 hiredman: Yeah

6:44 Chouser: well, they don't let you *change* metadata. You can use proxy to provide unalterable metadata when you creating the instance.

6:45 hiredman: well, I guess there is that

6:45 Chouser: which actually sounds about perfect for arity

6:46 cemerick: ah, AFn has metadata. I'd think IFn would extend IObj.

6:46 Chouser: what would this metadata look like? a set of the accepted arities?

6:46 but then what about variadics?

6:46 cemerick: I'm not sure yet. We need a little more than just arity (type info, aaack!), but it'd always be immutable.

6:47 I don't think we have any variadic fns in this particular corner of things.

6:48 eh, maybe we should just pass around maps with a :fn key where the actual function lives. I'll bet we'll want to assoc some amount of stuff into a fn's 'metadata' eventually.

7:17 Chouser: recur is a bit of a problem

7:18 it refers to it's own kind of scope -- not dynamic, not lexical of the sort that can be closed over.

7:21 cemerick: that's the tradeoff for constant-space stack usage, right? The "real" solution is TCO or trampolining.

7:23 Chouser: It seems it might be theoretically possible to recur to a named loop in your lexical scope...

7:23 hm, maybe not -- if you close over that name, then call the closure from outside that lexical scope, where does the recur go?

7:23 cemerick: oh, so you could choose to recur to the next loop up, or optionally to an outer loop or the fn you're in?

7:24 cmvkk: what are you trying to do?

7:24 Chouser: cemerick: yeah, that's what I was thinking, but I specifically wanted to be able to close over that name, so that I could 'recur' to a named loop instead of having to recurse to a named fn.

7:25 cmvkk: fix error-kit

7:25 ugh, sounds like I might be asking for continuations without knowing it.

7:25 cemerick: you inch towards a reified environment at that point, I think.

7:25 indeed

7:26 that's not entirely horrible in the scope of error-kit, though, right?

7:27 Chouser: what's not horrible, continuations?

7:28 cemerick: within the scope of using error-kit facilities, requiring people to work with a separate, reified environment

7:28 penalty there, certainly

7:29 Cark: i'm trying to use clojure.contrib.pprint/pprint it works ok in the repl, but i can't seem to make it work from an executable jar file, any idea on how i could make it work ?

7:29 Chouser: oh, I see. But building that kind of reified env is more than I'd like to do. So far I've avoided any real code-walking.

7:30 my problem is that the body of a 'handle' form is a closure, so that it can use names from the 'with-handler' scope. But since the handler can do 'continue-with' which requires it be executed in the dynamic and call-stack scope of the 'raise'

7:31 that's all fine until someone tries to 'recur' from inside a 'handle' form, excepting it to jump back to a 'loop' outside of the 'with-handler'

7:31 cemerick: ah, I get it

7:31 well, how does CL do it in the face of goto?

7:32 Chouser: no idea. But since it has neither 'continue-with' (as far as I can tell) nor 'recur', it may just not have that problem.

7:33 cemerick: well, recur is just a special case of goto

7:34 continue-with (if I understand the semantics) is the trickier problem, it seems. That's a big jump from an error providing a set of fixed restart options.

7:35 Cark: what error/problem are you seeing?

7:35 Cark: nothing, it just does not output a thing

7:35 Chouser: I already toss bits of extra data up the call stack -- I suppose I could provide a 'kit/recur' that causes the recur to happen at the right scope.

7:36 I could even code-walk and try to replace 'recur' with 'kit/recur' where appropriate

7:36 cmvkk: that seems like the only option, if you're trying to remove a point of recurrance

7:38 Chouser: but I'm sure it's another strike against ever getting this into core (if there was any chance left anyway)

7:38 cmvkk: would it be possible for a no-recurring-fn special form to exist, out of curiosity?

7:38 an fn that doesn't affect recur, i mean

7:39 cemerick: Cark: I'm afraid I've never used it myself. In general, it sounds like *out* isn't being bound properly, or something similar.

7:40 Chouser: seems like two separate issues: implementing delimited continuations, and secondly building error-kit on top of them

7:40 Cark: could be that, thanks cemerick

7:43 cgrand: Chouser: mutable state + ugly macroing can help you intercept a recur without code walking

7:44 hmmm, no it won't work without knowing the number of args to recur which require code walking :-(

7:45 cemerick: hrm, more ammo for my decorate-fns-with-arity-info suggestion ;-)

7:46 Drakeson: how can I memoize a lazy Var? imagine (def fibs (lazy-cat (list 1 2) (map + fibs (drop 1 fibs))))

7:47 Chouser: cgrand: how would I prevent 'recur' from just doing it's normal special-form thing? no macro or fn is going to get in the way, is it?

7:48 cgrand: I was thinking of introducing a... hmm wait, must check something

7:53 Cark: cemerick : output wasn't flushed before my program exited

7:53 thanks

7:53 cemerick: Cark: ah-ha! :-)

7:53 heh, I didn't no anything

7:54 * hiredman punches vimclojure

7:56 lisppaste8: cgrand pasted "bad idea" at http://paste.lisp.org/display/78118

7:57 kotarak: hiredman: a problem?

7:57 Chouser: ah! very nice.

7:58 cgrand: where "nice" == "twisted and evil"

8:01 cgrand: did you try using a variadic fn instead of loop?

8:02 doesn't work, because recur wants you to pass the variadic part as a seq

8:04 huh, you can't 'recur' from a catch or finally either. maybe not supporting 'recur' in a 'handle' isn't so bad.

8:06 triddell: Does anyone know of a change (in the last month or so) which would cause "Wrong number of args passed" error on gen-classed code that was working just fine before?

8:08 From Java I'm calling a function which then calls another Clojure function and I get this error now. The method which is called from Java includes "this" are the first argument but the inner call doesn't (and didn't need to before.)

8:10 Probably doesn't make much sense, but I'm calling a function with four arguments (which takes four arguments) and now I'm getting this error.

8:15 lisppaste8: slashus2 pasted "stm test" at http://paste.lisp.org/display/78119

8:15 slashus3: Why doesn't await-for stop the agents after the timeout in this case?

8:16 oh... wait, I need to add print-agt to the await-for

8:17 I don't think that worked either.

8:17 And I am curious to why the print agent isn't printing anything.

8:18 Beware. Be sure to kill this process asap, it will eat up your memory.

8:19 cmvkk: well nothing gets sent to print-agt until after the other agents have finished

8:20 slashus3: cmvkk: Why don't they timeout?

8:20 cmvkk: anyway, when i run that it returns for me

8:21 slashus3: Does it return false?

8:21 cmvkk: yes.

8:21 after about 5 seconds, as expected.

8:21 slashus3: You better kill the process. They are still running.

8:21 cmvkk: yeah. they are.

8:21 slashus3: It will return nil if it returned because of a timeout, but it returns false?

8:22 cmvkk: yeah that's weird, because it's supposed to be nil or non-nil.

8:22 slashus3: right

8:22 cmvkk: but if you wanted to test against it, why would you return false?

8:22 and being able to test against it is the point of returning nil or non-nil

8:23 slashus3: I would think that it should kill all of the agents after the timout, but it just kills my computer slowly after returning.

8:23 That is why I am using await-for there.

8:24 I wanted it to print out the results of the two agents for 5 seconds and stop.

8:24 cmvkk: it's an infinite loop, and all it does is sen-off and commute.

8:24 assuming those things are waiting until after the original fn returns

8:24 then they just build up a huge queue, then when await-for stops them, they do all the send-offs at once?

8:24 maybe?

8:25 slashus3: Well with each transaction, I would think there should be a send-off.

8:25 I would think that those prints would be interleaved with the other agents.

8:25 I know it is bad practice, but even if you use (println) it won't kill them after 5 seconds.

8:29 If await-for doesn't work in this case, how would you handle this situation?

8:31 :-(

8:34 There is no way to control agents with infinite loops?

8:34 kotarak: slashus3: you have to probably rewrite them to send to themselves.

8:35 slashus3: kotarak: I guess that is the solution. await-for won't stop agents that have infinite loops.

8:36 kotarak: I think await only waits for them to finish. But maybe I'm mistaken...

8:36 (doc await-for)

8:36 clojurebot: Blocks the current thread until all actions dispatched thus far (from this thread or agent) to the agents have occurred, or the timeout (in milliseconds) has elapsed. Returns nil if returning due to timeout, non-nil otherwise.; arglists ([timeout-ms & agents])

8:36 slashus3: apparently it returns false if the agent is still going after the timeout.

8:43 lisppaste8: slashus2 annotated #78119 "stm test again" at http://paste.lisp.org/display/78119#1

8:43 slashus3: kotarak: This still doesn't stop when await-for is called.

8:44 kotarak: slashus3: I don't think, that await-for stops something.

8:46 You'll have to use some flag: (send *agent* (fn this-fn [_] (when @*running* (send *agent* this-fn)))), when you want to stop the agent loop, you have to do a (reset! *running* false) (assuming that *running* is an atom)

8:46 Lau_of_DK: Good evening all

8:46 kotarak: Hi Lau

9:09 cgrand: Chouser: varidic support in recur was what I checked just before pasting :-)

9:22 twansit: Hello all!

9:22 Lau_of_DK: Yo dude

9:22 twansit: question what is the most effecient way to turn a json object to a clojure object with the keys as keywords?

9:23 or is it just not advisable

9:23 danlarkin: (json/decode-from-str string) of course!

9:23 twansit: ah..is that in clojure-contrib?

9:24 danlarkin: there is a json lib in contrib yes, but there's also clojure-json

9:24 twansit: yeah the contrib version doesn't do this

9:25 kotarak: o.O sheesh I really got out of sync with contrib...

9:25 twansit: danlarkin : i see you are plugging yourself :)

9:25 danlarkin: somebody's gotta :)

9:27 hiredman: ~google clojure-json

9:27 clojurebot: First, out of 1880 results is:

9:27 danlarkin&#39;s clojure-json at master - GitHub

9:27 http://github.com/danlarkin/clojure-json/tree/master

9:27 twansit: gittin

9:27 gittin' it

9:28 kotarak: hiredman: why do you hit my poor vc?

9:28 hiredman: clojurebot uses clojure-json for google search results

9:28 kotarak: I retract my hitting

9:29 kotarak: hiredman: oh ok, thought there was a problem ...

9:30 hiredman: I am getting weird indentation, but it is on a scrap file, so maybe I have a unbalanced paran somewhere

9:30 kotarak: ok, hopefully. There are some corner cases. But they should happen rarely.

9:31 twansit: danlarkin: thanks!

9:33 danlarkin: twansit: my pleasure

9:38 erohtar_: is there a way to pass a dynamically constructed vector to the binding form?

9:39 kotarak: erohtar_: (try (clojure.lang.Var/pushThreadBindings {varA valA varB valB}) ..... (finally (clojure.lang.Var/popThreadBindings)))

9:52 pjstadig: clojurebot: what is our mascot?

9:52 clojurebot: the official mascot of clojure is a futuristic ninja robot

9:54 Lau_of_DK: pjstadig, I was under the impression that danlarkin was our mascot?

9:54 danlarkin: oh jeez

9:55 pjstadig: Lau_of_DK: danlarkin is a futuristic ninja robot??!!!

9:55 opqdonut: wow!

9:55 Chouser: that's so much better than any of the historical ninja robots

9:55 Lau_of_DK: Thats certainly true

9:56 pjstadig: historical ninja robots are so 1999

9:56 Lau_of_DK: ~at least the were so 1999, when suddenly...

9:56 clojurebot: CLABANGO!

9:56 pjstadig: clojurebot: historical ninja robots is <reply>historical ninja robots are so 1999...

9:56 clojurebot: In Ordnung

9:56 pjstadig: ~historical ninja robots

9:56 clojurebot: historical ninja robots are so 1999...

9:57 pjstadig: clojurebot: futuristic ninja robots is <reply>sooo much better than historical ninja robots

9:57 clojurebot: c'est bon!

9:57 pjstadig: ~futuristic ninja robots

9:57 clojurebot: sooo much better than historical ninja robots

9:58 pjstadig: hiredman: these are facts that should have been programmed into clojurebot from the beginning....I'm astonished!

9:59 erohtar__: kotarak: sorry - having network problems today

11:08 taggart: Can anyone see where I'm ging wrong with this port of an SICP example?

11:08 (def fibs (lazy-seq (cons 0 (cons 1 (map + (next fibs) fibs)))))

11:09 getting a stack overflow so it's not as lazy as I had hoped

11:12 Chouser: the problem is that cons is not itself lazy

11:13 so as soon as you try to take one value from fibs, it computes 0 and 1 and (map ...)

11:13 taggart: I thought that was dealt with by the lazy-seq

11:13 Chouser: lazy-seq only makes one level lazy

11:13 taggart: ahh

11:14 Chouser: without it, you'd get the overflow as soon as you def, instead of only after you try to take something from it

11:14 taggart: map is lazy though, so wouldn't I just the 0 and 1 be resolved immediately?

11:15 Chouser: map is lazy, but cons is not. the second cons forces map to do one step

11:16 taggart: ah, and then the cycle starts

11:16 got it, thx

11:16 Chouser: ...which in turn forces fibs itself, which does the cons's, ... right.

11:16 so find the one expression that you need to delay, and put lazy-seq around that instead.

11:17 taggart: (def fibs (lazy-seq (cons 0 (lazy-seq (cons 1 (lazy-seq (map + (next fibs) fibs)))))))

11:17 Chouser: I keep forgetting to try a more Socratic method.

11:17 kotarak: Why so many lazy-seqs?

11:17 taggart: I guess I really only need one around map?

11:18 Chouser: "so where would you put lazy-seq to avoid the recursion?"

11:18 "what is the value of delaying the evaluation of the constants 0 and 1?"

11:18 :-)

11:18 taggart: nada

11:19 (def fibs (cons 0 (cons 1 (lazy-seq (map + (next fibs) fibs)))))

11:19 woot

11:19 opqdonut: :)

11:21 Chouser: How would the 'fibs' definition look if it were written by scgilardi and put in clojure.contrib.lazy-seqs?

11:22 pjstadig: what is the air speed of a swallo?

11:22 *swallow

11:22 Chouser: ~google what is the air speed of a swallow?

11:22 clojurebot: First, out of 227000 results is:

11:22 What is the air-speed velocity of an unladen swallow

11:22 http://indianajones.arystoteles.pl/swallow.htm

11:43 lisppaste8: slashus2 pasted "stm test again" at http://paste.lisp.org/display/78128

11:45 slashus3: What is causing the strange print results? Since running was set to false and I await all of the agents, should the function only return when all of the agents are finished?

11:46 Chouser: await only waits for actions dispatched from the current thread or agent.

11:48 stuhood: its probably implemented as some kind of sentinel value in the queue that the agent acts on to call back to the awaiting thread

11:48 ~def await

11:49 yea

11:50 slashus3: How would I go about keeping the function from returning until all of the agents have finished their business?

11:51 Chouser: you could use CountDownLatch yourself.

11:51 slashus3: Is there any other way?

11:52 Chouser: genearlly if you need specific blocking behavior for task management, you'll need to use something from java.util.concurrent

11:53 slashus3: I think I found the solution.

11:53 Chouser: One exception is 'future', but I doubt that would help you here.

11:54 lisppaste8: slashus2 annotated #78128 "fixed?" at http://paste.lisp.org/display/78128#1

11:54 slashus3: Chouser: I made the send-off the last thing in the agent.

11:54 I guess it sort of fixes the problem?

11:55 kotarak: Where do the file and line information in the exceptions come from? I set Compiler/LINE and Compiler/SOURCE, but get only Unknown Source...

11:56 stuhood: slashus3: you'd still have a race

11:56 Chouser: slashus3: not really. I'm still seeing extra prints after the fn returns

11:56 slashus3: and I don't think await is doing you any good there.

11:57 stuhood: anything generated by the last action sent to the agent will go into the queue after the Latch sent in by (await)

11:57 slashus3: Mine counts to 49 every time. I suppose I may get that result if I run it enough times.

11:58 Chouser: kotarak: (binding [*source-path* "foo"] (eval '(asdf)))

11:58 that works for me.

11:58 slashus3: Would it make the difference than I am on a single core computer?

11:59 stuhood: slashus3: that might hide the race condition, yea

11:59 kotarak: Chouser: Hmm.. *source-path*. Is this handled in the Reader? The compiler seems to use Compiler/SOURCE....

11:59 Chouser: kotarak: those are the same Var

12:00 slashus3: ugh... I didn't think this would be so hard.

12:00 Chouser: ,clojure.lang.Compiler/SOURCE

12:00 clojurebot: #'clojure.core/*source-path*

12:00 kotarak: hmmmm.....

12:01 Chouser: slashus3: why don't you want to use CountDownLatch? make one that starts at 2, then have each agent action countdown when they quit running.

12:01 then you can await on the latch, and it'll block until they're done.

12:02 slashus3: Chouser: I need to figure out how to use it.

12:02 Chouser: slashus3: or perhaps stop having the agents send to themselves -- do a regular loop that terminates if @running is false. Then await should do what you want.

12:02 clojurebot: we can't stop here! this is bat country!

12:02 stuhood: i think rhickey chose to call them Agents instead of 'Actors' for a reason: the mainloop case isn't what he was going for

12:03 Chouser: though that's how he uses them in the ant demo

12:03 stuhood: hmm.

12:04 so its a single agent call then, with a function containing an infinite loop?"

12:04 slashus3: It sends-off itself

12:04 Chouser: oh, no, I meant the send-to-self loop

12:04 right

12:05 stuhood: weird.

12:05 kotarak: Chouser: sorry, I have to ask again. I want to set the file and line numbering and the eval some def. I would expect, that then the source info is set correctly. But in the stack trace only "Unkown Source" shows up....

12:05 Chouser: the main reason I've heard for using send-to-self rather than a loop/recur is so that you can redef the action and get new behavior without restarting anything.

12:06 kotarak: Is there a remedy?

12:06 Chouser: kotarak: the example I posted above gives me this error: java.lang.Exception: Unable to resolve symbol: asdf in this context (foo:39)

12:06 stuhood: Chouser: that's true, but implementation wise your loop would be moving between threads and cores on your cpu, which would suck for performance

12:06 hiredman: Chouser: also so sends get released

12:06 Chouser: so it looks like it's getting the source name ok. I'm not sure about the line number.

12:07 kotarak: -.-

12:07 Ok. Will try again.

12:07 Chouser: stuhood: hm could be, though moving between threads doesn't necessarily mean moving between cores, right?

12:08 kotarak: For the line number, I have this by the way: (proxy [LineNumberingPushbackReader] [reader]

12:08 (getLineNumber [] (+ offset (proxy-super getLineNumber)))))

12:08 Proxy is cool. :)

12:08 stuhood: perhaps the agent could simple loop calling a defn'd fun, and then you could redefine the fun

12:08 erohtar_: i have to ask again (having network problems) -

12:08 slashus3: Should I be using regular java threads with this, or is this the right way to model the problem?

12:08 clojurebot: ?

12:08 erohtar_: is there a way to use the binding form meta-programmatically

12:09 kotarak: erohtar_: you have to use Var/push(pop)ThreadBindings directly.

12:10 erohtar_: kotarak: those methods accept a map? the vars are passed as keys?

12:10 kotarak: erohtar_: yes, what binding uses underneath.

12:10 * kotarak misses again (binding* map thunk)

12:11 erohtar_: where can i find the documentation?

12:11 slashus3: I have no idea how to use CountDownLatch here.

12:11 Do I send the latch to the agent?

12:11 erohtar_: kotarak: where can i find the documentation? is there javadoc?

12:11 stuhood: slashus3: it would be in a var, like 'running'

12:11 kotarak: erohtar_: no, but you can look at the definition of binding

12:12 erohtar_: ok

12:12 kotarak: ~def binding

12:12 stuhood: slashus3: when the agents are done running, have them .countDown on the latch

12:12 slashus3: (.countDown agt alatch)

12:12 erohtar_: kotarak: will do, thanks!

12:13 Chouser: (defmacro nil-binding [n & body] (apply @#'binding [n nil] body))

12:13 kotarak: how about that?

12:14 hm

12:15 wait, what's wrong again with: (defmacro nil-binding [n & body] `(binding [~n nil] ~@body))

12:15 stuhood: slashus3: (.countDown alatch)

12:16 Chouser: perhaps what is missing is some kind of agent shutdown functionality that prevents new items in the queue for the agent

12:16 clojurebot: Chouser might make night

12:17 kotarak: Chouser: I'm not sure what's the nil about, but I want a driver for binding that takes a map (programmatically created at runtime) and a thunk being invoked as the body. A macro won't help here.

12:17 Chouser: stuhood: well, there is shutdown-agents, but that's rather a large hammer

12:17 kotarak: ah, right of course. Sorry, took my eye off the ball there.

12:17 slashus3: (shutdown-agents) messes up everything after that. Maybe something a little lighter wait.

12:17 weight*

12:18 stuhood: slashus3: yea

12:19 slashus3: I am looking at the source code for await, and I don't see what I would do that would be different than what await does with CountDownLatch.

12:19 Chouser: so right, you have to use the static methods of Var directly.

12:20 stuhood: slashus3: await adds the latch to the end of the agent queue, but the agent is running in a separate thread, and it can add an item after the latch

12:22 so immediately after await returns, it will run the queued action

12:23 * slashus3 kills the queue.

12:23 stuhood: actually, i guess you could await it twice?

12:24 ah, no.

12:25 Chouser: you need to make sure the countDown is done after the agent has noticed that @running is false

12:25 I think the only way to do that is in the agent action itself -- when it sees @running false, countDown.

12:26 slashus3: Chouser: I tried running the agent's body in a (while @running , but the output just bursts out at the end, and I still get some weird output.

12:26 stuhood: slashus3: actually, i think running await twice will work

12:27 Chouser: hm, that's an interesting point -- you might need to (flush) too, to prevent output coming after the prompt.

12:27 slashus3: stuhood: It seems like it should.

12:28 stuhood: because the first time guarantees that the @running has been seen, and the second time makes sure that the final action queued from within the agent is cleared

12:28 slashus3: That isn't a very elegant solution though.

12:28 If that is the case, in the await function, could you just (send agent count-down) twice?

12:29 stuhood: no, you have to wait for the first (await) to return

12:29 slashus3: okay

12:29 stuhood: because when it returns there may-or-may-not be one last action sitting in the queue, which you need to wait for

12:30 slashus3: I think await would be more useful if it had the wait until all queued agents were finished.

12:31 stuhood: agreed.

12:32 maybe (await-shutdown) that would prevent new actions for an agent

12:32 slashus3: (await-shutdown agt1 agt2 print-agt)

12:37 maybe (await-shutdown can be implemented by just calling await twice on the agents sent in?

12:37 stuhood: the only problem would be the agent api changes: (send) would need a 'agent is shut down' failure case

12:37 slashus3: that works here because you only have two threads adding to the agent queue

12:37 slashus3: Wait, that only works because I am using *running*

12:37 Okay, yeah

12:39 stuhood: slashus3: maybe you could bring this use case up on the list?

12:39 you shouldn't have to resort to java code to accomplish this

12:39 slashus3: I wonder what would be the best way to present it? With this example?

12:40 stuhood: you only need 1 agent to demonstrate it

12:43 oh... (send) already has an error case if (shutdown-agents) has been run

12:44 so there would be good symmetry with a (shutdown-agent) function

12:45 kotarak: Chouser: just for the records: the Vars to modify are SOURCE and SOURCE_PATH. I'm not sure, but it seems, that one has to set both... Now it works. :D

12:46 slashus3: stuhood: Would we have to use that exception when we determine if there are no agents in the agent queue?

12:46 Can't we just loop through the agents and (.getQueueCount a)

12:47 When all of the agent's (.getQueueCount a) is zero, we are finished?

12:51 Hmm this seems to work.

12:53 lisppaste8: slashus2 annotated #78128 "fixed??!" at http://paste.lisp.org/display/78128#2

12:53 slashus3: stuhood: Check this out.

12:55 Maybe I should await before the while in that function.

12:57 stuhood: Because not-every is not atomic, I want to be sure that there are no further agents being emitted.

12:57 sent

12:57 Then I would wait until the queue was empty.

13:01 lisppaste8: slashus2 annotated #78128 "added await to the await-shutdown" at http://paste.lisp.org/display/78128#3

13:02 slashus3: Chouser: Would this be an acceptable solution?

13:08 rosejn: Should any object implementing Associative be usable both like (obj :foo) and like (:foo obj)?

13:08 I'm implementing it in a proxy for a storage layer, and it only works with the key first.

13:08 slashus3: That seems to be the case.

13:10 rosejn: It seems that this error shouldn't be feasible then:

13:10 actual: java.lang.ClassCastException: clojure.proxy.java.lang.Object$Associative cannot be cast to clojure.lang.IFn

13:11 slashus3: hmm

13:11 Maybe not then.

13:11 rosejn: Yeah, strange...

13:13 kotarak: rosejn: It probably has to implement clojure.lang.IFn to be used in the functions position.

13:13 rosejn: hmmmm, ok. I'll give it a try.

13:13 kotarak: thanks

13:14 kotarak: rosejn: invoke with one and two arguments is probably enough. (thing key) and (thing key default-if-not-found). This is the usual behaviour of maps, IIRC. You can have look at their implementation.

13:17 slashus3: kotarak: Looks like AFn takes in IPersistentMap

13:19 rosejn: APersistentMap extends AFn, which takes in an IPersistentMap.

13:29 rosejn: awesome!

13:29 kotarak: that worked, thanks

13:29 just had to implement invoke

13:29 kotarak: rosejn: good to hear :)

13:31 rosejn: kotarak: Hey, you do vimclojure right?

13:31 kotarak: rosejn: right

13:31 rosejn: cool. Quick question. In a number of places it seems to indent more than I want it to.

13:32 kotarak: rosejn: do you have an example?

13:32 rosejn: For example:

13:32 (deftest my-test []

13:32 (test-stuff ...))

13:32 Where I'd like the (test-stuff ...) to just be two spaces over.

13:33 kotarak: rosejn: ok. try this: :setlocal lw+=deftest

13:33 Does this work for you?

13:33 rosejn: great

13:33 yeah, that worked

13:34 kotarak: rosejn: You can put such clauses in ~/.vim/after/ftplugin/clojure/my-lispwords.vim. I'm working on some heuristic, but it will likely be fragile.

13:35 rosejn: got it, thanks for all the work you've done for vim

13:35 kotarak: np

13:35 rosejn: I'm using it daily now, with the repl and everything

13:35 fairly often I get errors and I have to restart the ng-server though

13:35 it would be nice if it could be started automatically

13:36 also if there were a way to clear the repl state, to load libraries fresh

13:36 kotarak: Hmmm... I'll look into starting it automatically. However, the next version will be more robust on missing server.

13:36 rosejn: great

13:36 kotarak: you can reload libraries via (require :reload-all 'the.library)

13:37 rosejn: yeah, but weird errors can crop up on redefinition after refactoring things

13:37 like moving a function from one namespace to another, where they were using each other

13:37 it complains of multiple definitions, so you have to unmap the original

13:38 kotarak: Ah. Ok. That may happen.

13:41 Hmm... Maybe some Repl command like ",nuke the.library".

13:42 rosejn: yeah, that would be perfect

13:43 maybe it should be a different argument to require... (require :fresh 'my-lib)

13:44 Actually, I guess those are just functions being called by require.... so a new function that nukes then reloads.

13:47 kotarak: rosejn: Thanks for the feedback. Gotta go to bed now. Bye.

13:48 rosejn: kotarak: thanks for the tools. Guten abend.

14:11 replaca: erohtar_: if you want to see an example of binding using runtime discovered maps, look at clojure/contrib/pprint/pprint.clj

15:30 cp2: hiredman: kevin.clj for life !

15:31 hiredman: kitten: totally

15:31 er

15:31 :(

15:39 cp2: why are the clojure shirts on zazzle so expensiv

15:39 e

15:39 i dont want to pay like $60 for 3 shirts

15:54 Drakeson: how can I pop a certain element (nth) of a vector or list, whichever is easier?

15:56 cp2: what would you name a 3 byte integer value? im trying to think of something that doesnt sound lame

15:56 hiredman: pop?

15:57 Drakeson: hiredman: I want to remove nth element of a vector/list

15:58 hiredman: Drakeson: vectors and lists are not designed for that sort of behaviour

15:58 you might look at filter or remove

15:59 cp2: hiredman: any suggestions ? :)

15:59 hiredman: tryte

15:59 cp2: ah

15:59 i like that

15:59 thanks

16:03 Drakeson: hiredman: deleting an element from a linked-list is very cheap, once you can refer to the element. It sounds a bit strange if it is not implemented here.

16:03 so, I guess I am missing something

16:06 hiredman: ,(doc pop)

16:06 clojurebot: "([coll]); For a list or queue, returns a new list/queue without the first item, for a vector, returns a new vector without the last item. If the collection is empty, throws an exception. Note - not the same as next/butlast."

16:07 hiredman: Drakeson: but clojure's library is based around sequences, not linked lists

16:08 Cark: it isn't cheap to find the nth element of a list in order to delete it

16:08 that's what sets are there for

16:08 hiredman: (doc rvec)

16:08 clojurebot: Excuse me?

16:08 Cark: though i agree that this function is missing

16:11 ,(doc ordered-set)

16:12 clojurebot: java.lang.Exception: Unable to resolve var: ordered-set in this context

16:12 Cark: ,(doc order-set)

16:12 clojurebot: java.lang.Exception: Unable to resolve var: order-set in this context

16:12 Cark: ,(doc sorted-set)

16:12 clojurebot: "([& keys]); Returns a new sorted set with supplied keys."

16:14 Drakeson: Cark: thanks

16:14 Cark: this was for my information, not trying to help you !

16:15 sometimes you need the ordered nature of a list and the add/remove capabilities of a set

16:15 that would require an ordered set data structure

16:15 but there is none in clojure

16:15 Drakeson: what I feel is missing (or I cannot find) is a standard way to point to an element (O(n) for finding nth in a list), and then call an imaginary pop-by-ref and get a new list without that element.

16:16 Cark: well you can use filter

16:16 it's "kind of" O(1) as it's lazy

16:21 cp2: O(1) (no guarantees!)

16:24 stuhood: ~def c.l.Agent

17:06 dysinger: If I call (with-open #^javax.mail.Folder folder forms*) is it going to not work because close takes true/false (expunge) ?

17:06 I can try it just curious

17:06 if there was any magic

17:06 stuhood: ha, i had the same question and never tried it, because i assumed there wasn't =/

17:06 magic, that is

17:09 dysinger: that's what I figured

17:09 you only get so much magic for free

17:10 stuhood: i love with-open though

17:11 it's more complete in python, with the 'with' statement and context managers

17:11 dysinger: yeah - ruby has similar with closure blocks

17:14 stuhood: i guess the java way would be to add an interface that an object could implement to play nicely with 'with-open'

17:14 and otherwise clojure would just attempt to call close()

17:15 dysinger: or you could wrote an alternate macro

17:15 stuhood: mm, indeed

17:15 ~def with-open

17:33 dakrone_hb: is anyone else having trouble building clojure-contrib using the clojure jar from svn?

17:34 Raynes: dakrone_hb: What do you mean by building? Compiling it? Usually you just jar it or copy the directories.

17:34 dakrone_hb: Raynes, http://pastie.org/439181

17:35 I was under the impression that you needed to build it

17:36 given the Getting Started page lists building it with ant

17:36 Raynes: dakrone_hb: Just cd to the directory of clojure-contirbs build file and "ant build"

17:37 dakrone_hb: Raynes, Target "build" does not exist in the project "clojure-contrib".

17:37 is the error

17:37 danlarkin: dakrone_hb: yeah, just "ant"

17:37 dakrone_hb: danlarkin, yea, I get http://pastie.org/439181

17:37 danlarkin: you don't need to specify clojure.jar

17:37 Raynes: I didn't mean to quote build, just ant.

17:38 danlarkin: that's only if you want to AOT compile

17:38 dakrone_hb: danlarkin, even though it warns that I should?

17:38 oh, okay

17:38 it warns things like pretty print won't work

17:38 Raynes: Enclojure has some neat new REPL features!

17:38 dakrone_hb: is thhat correct?

17:38 Raynes: :D

17:38 danlarkin: is your clojure up to date?

17:39 make sure you're on the google code SVN and not the sourceforge SVN

17:39 Raynes: All it does is jar everything, you don't even really have to jar it at all. All the ant script does is jar whats in src.

17:39 dakrone_hb: danlarkin, Ahhhhhhhhhh

17:39 danlarkin, it's been a while since I checked out ;)

17:39 danlarkin, how long ago did Clojure switch?

17:40 danlarkin: December? I think?

17:40 dakrone_hb: that would definitely be some changes

17:41 danlarkin, I'm sure this will fix it, thank you much

17:45 danlarkin: dakrone_hb: let us know if it doesn't

17:46 hiredman: ~latest

17:46 clojurebot: latest is 1338

17:51 dakrone_hb: danlarkin, worked great, thanks :)

17:59 danlarkin: dakrone_hb: fantastic

17:59 dysinger: whats the best idiom for recur on exception with a finally ?

18:00 it says I cant recur because my recur is not on the tail

18:02 ~(loop [x 1] (try (println "hello") (catch Throwable t (recur x))))

18:02 clojurebot: BUENOS DING DONG DIDDLY DIOS, fRaUline dysinger

18:03 dysinger: seems like retry on exception is common enough for IO stuff

18:03 at least for the computerwebs and tcp/ip

18:04 dreish_: The only think I can think of would be a little ugly, so I'd wrap it in a macro, but you could return either a value or the exception, then check outside the try; if it's an exception, recur.

18:05 danlarkin: you could also possibly use a trampoline

18:05 dreish_: (defmacro retry-on-exception [& exprs] ...)

18:11 dysinger: clojure so totally scratches my lisp itch but with tens of thousands of libs

18:11 yayz

18:28 replaca: dakrone_hb: I just added the pretty print stuff to contrib and it require AOT, thus the warning

18:28 so now it's better to do a "real" compile

18:29 Chouser: replaca: was requiring AOT necessary or just convenient?

18:30 replaca: Chouser: necessary, cause I need to make classes that wrap java.io.Writer

18:30 *needed

18:30 Chouser: and proxy was insufficient?

18:30 replaca: Chouser: remember our discussions from a *looong* time ago

18:31 Chouser: heh. apparently not.

18:31 replaca: I tried super-hard to make proxy work but it just didn't have what I needed

18:31 Chouser: you needed some state and a sane way to get at it from the object itself?

18:31 replaca: I came up with an idea for a super-proxy, but I haven't done that yet

18:31 yeah, there's actually a lot of state in the current application

18:32 Chouser: I've gotten into the habit recently of deriving a proxy class from something and also implementing IDeref

18:32 replaca: cause all the info is kept in the writer

18:32 dakrone_hb: I'm sorry for the dumb question, but what does AOT stand for?

18:32 clojurebot: for is not used often enough.

18:33 replaca: Ahead of time compilation

18:33 dakrone_hb: replaca, ahh, thanks

18:33 Chouser: then I can implement the deref method, and use @ to get at whatever object state I need.

18:33 replaca: But really, Chouser :gen-class is not something to be afraid of!

18:34 Chouser: I don't fear it. I dislike it.

18:34 replaca: :-)

18:34 hiredman: not afraid, annoyed by

18:34 Chouser: "make" is for C++ and Java.

18:35 replaca: But, more to the point, PrettyWriter has a bunch of methods on the class that make sense as methods

18:35 slashus2: Chouser: Sorry to bring this up again, but did you ever see my solution to the agent problem?

18:35 replaca: Chouser: or Lisp or Haskell - everything but perl, ruby and python

18:36 and even python guys use the compiler for stuff they load all the time

18:36 thus the plethora of .pyc files

18:37 Chouser: slashus2: interesting. I assume it works?

18:38 slashus2: Chouser: It seems to work on my dual core machine.

18:38 Chouser: replaca: optional AOT for performance or whatever doesn't bother me, but Clojure is has so much less state than other systems, it's a shame to require the on-disk state of compilation just to accomplish a particular task.

18:38 replaca: One nice thing about :gen-class is that the implementation can be completely dynamic, only the interface requires loading

18:38 slashus2: Chouser: I think the function should probably be called await-finished instead of await-shutdown.

18:38 Chouser: replaca: yes, it's a pretty impressive compromise, but still not as nice as proxy.

18:38 replaca: Chouser: yeah, I hear you. Unfortunaltely what I was doing here was really writing a Java class in clojure

18:39 Chouser: if proxy worked for the use case, yes :-)

18:39 slashus2: Chouser: Maybe I should make a proposal on the list?

18:39 Chouser: slashus2: two possible issues: you're doing a busy wait after the blocking await, and you're using an implementation detail of agents

18:39 replaca: the alternative was pretty limiting, where you wouldn't be able to be pretty across calls

18:40 Chouser: replaca: hm. giving up user features isn't acceptible.

18:40 replaca: which would be nasty for apps that were reformatting larger chunks of stuff

18:40 Chouser: slashus2: of the two, the busy wait would bother me more.

18:40 replaca: but I still like the idea of a super-proxy :-)

18:40 slashus2: Chouser: Is there a way to do it without the busy wait?

18:44 Chouser: slashus2: it's important to be mixing refs and agents like this?

18:46 slashus2: huh?

18:46 Chouser: agt1 and agt2 sotre state that you apprently aren't using

18:47 store

18:47 slashus2: Chouser: I could probably do it a different way, but I was testing out refs.

18:47 Chouser: ok

18:48 slashus2: It was only an exercise to learn the behavior of agents, etc.

18:48 Chouser: sure

18:48 I'm just feeling out the constraints of your exercise. :-)

18:49 slashus2: There are probably many situations were you would want to wait until all of the agents finish their queues before returning a function.

18:54 lisppaste8: Chouser annotated #78128 "a couple options for slashus2" at http://paste.lisp.org/display/78128#4

18:54 hiredman: slashus2: I would uses agents for that

18:54 er

18:54 wouldn't

18:55 for map/reduce you can use pmap/reduce

18:55 pmap uses the agent threadpool via futures

18:56 replaca: Chouser: do you have some examples of your proxy + Ideref solution - I'll look at that and see if I could use it

18:57 slashus2: Chouser: So there is no general solution like my await-shutdown that doesn't use a busy wait?

18:58 Chouser: slashus2: oh, there may be... perhaps using watchers or something.

18:59 slashus2: hiredman: I know this isn't the best way to do this, but I was just wanting to try out the behavior of the STM.

19:00 Chouser: replaca: this is on a different topic, but includes an example of proxying IDeref to carry some mutable state: http://groups.google.com/group/clojure/msg/79a09fa877cb48d0

19:01 replaca: Chouser: thanks, I'll check it out

19:02 Chouser: ok, g'night all.

19:02 slashus2: Chouser: Hmm. Watchers monitor for a change of state... goodnight

19:03 replaca: goodnight Chouser

19:09 slashus2: I wonder why I would want to use a watcher inside of a watch in this case.

19:09 instead*

19:23 rlb: Is there already any easy way to treat a large binary file of 64-bit integrers as a (lazy) sequence?

19:24 s/integrers/integers/

19:35 replaca: rlb: not that I know of, but duck-streams/read-lines does it with strings. Maybe you could adapt it?

20:42 banisterfiend: what's the name of the clojure repl?

20:43 rlb: replaca: ok, thanks. One of the things I'm trying to do is keep track of what's effectively a 10 or so million element hash table mapping 128-256 bit values to an integer triple. I may just use sqlite or jdbm, but I was just looking around clojure itself...

20:43 banisterfiend: in debian, it's clojure-repl, but otherwise I just invoked it manually.

20:43 banisterfiend: If you mean the class, it's clojure.lang.Repl.

20:44 banisterfiend: thx

20:44 rlb: and if you want readline-alike:

20:44 java -cp /usr/share/java/jline-0.9.94.jar:/usr/share/java/clojure.jar:/usr/share/java/asm3-commons.jar:/usr/share/java/asm3.jar jline.ConsoleRunner clojure.lang.Repl

20:44 banisterfiend: is tehre another name for the repl?

20:44 i think i installed it ages ago, but i cant remember what it's called

20:44 clojure-repl doesn't work

20:45 rlb: Well, the repl class is in clojure.jar.

20:45 (normally)

20:47 banisterfiend: thanks rlb

20:47 you have mad skillz

21:20 cp2: Microsoft Boasts 96% Netbook Penetration

21:21 how very kinky

22:57 tsdh: Hi. In my clojure code I want to run a java classes main method. That's no problem, but is it also possible to do that in an own JVM with own JVM args?

23:18 cgrand: tsdh: if you want to start another JVM then there's no more facility than for starting a random program. See clojure.contrib.shell-out

23:20 tsdh: cgrand: Basically what I want is something like ant's fork, e.g. the new JVM should use the same classpath, etc. But ok, I'll use shell-out till I find something that suits my needs better.

Logging service provided by n01se.net