#clojure log - Mar 16 2009

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

0:13 Mec: does emacs have code completion?

0:22 Raynes: Mec: There is a hack in the wikipage to make it tab complete.

0:22 iirc

0:37 Mec: ,(replace {0 'b 1 'a} ['a 'b])

0:37 clojurebot: [a b]

0:38 Mec: is there a way to replace by index instead of by value

0:39 dreish: assoc

0:40 Mec: ah nice, thanks

1:21 any chance of a library function that creates an infinite sequence by repeatedly calling a function on an initial value?

1:21 smells like recur

1:21 err iterate

1:36 hiredman: clojurebot: do you understand emotion?

1:36 clojurebot: this model does not support emotionml as spec'd in http://www.w3.org/2005/Incubator/emotion/XGR-emotionml-20081120/

1:40 hiredman: clojurebot: does rest ever return a unicorn?

1:40 clojurebot: rest never returns a unicorn

1:40 cmvkk_: Mec: repeatedly ?

1:41 Mec: naw iterate is what i wanted, repeatedly doesnt take an init value

1:41 cmvkk_: oh, aha.

1:59 Mec: ok how do you find the index of a value in a vector, i must be getting too tired

2:14 hiredman: ,(find [1 2 3] 3)

2:14 clojurebot: nil

2:14 hiredman: hmm

2:15 ah

2:17 ,(map-invert [1 2 3])

2:17 clojurebot: java.lang.Exception: Unable to resolve symbol: map-invert in this context

2:18 hiredman: ,(clojure.set/map-invert [1 2 3])

2:18 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: Integer

2:18 Mec: surely there's a way to search thru a vector

2:21 hiredman: ,(let [v [1 2 3]] (first (filter #(= 3 (v %)) (range (count v)))

2:21 clojurebot: EOF while reading

2:21 hiredman: ,(let [v [1 2 3]] (first (filter #(= 3 (v %)) (range (count v))))

2:21 clojurebot: EOF while reading

2:21 hiredman: bah

2:21 dunno

2:21 it's never come up

2:21 ,(let [v [1 2 3]] (first (filter #(= 3 (v %)) (range (count v)))))

2:21 clojurebot: 2

2:22 hiredman: wait

2:23 ,(map #(.getName %) (.getMethods (class [])))

2:23 clojurebot: ("withMeta" "withMeta" "withMeta" "nth" "assocN" "assocN" "count" "pop" "pop" "cons" "cons" "cons" "empty" "create" "create" "create" "seq" "equiv" "valAt" "valAt" "assoc" "assoc" "entryAt" "rseq" "invoke" "add" "add" "get" "hashCode" "compareTo" "indexOf" "clear" "equals" "toString" "length" "isEmpty" "lastIndexOf" "contains" "addAll" "addAll" "size" "toArray" "toArray" "iterator" "remove" "remove" "containsKey" "set" "c

2:23 hiredman: ,(.indexOf [1 2 3] 3)

2:23 clojurebot: 2

2:23 hiredman: :P

2:26 slashus2: ,(.length [1 2 3 4])

2:26 clojurebot: 4

2:27 hiredman: ,(.clear [])

2:27 clojurebot: java.lang.UnsupportedOperationException

2:28 Mec: well now

2:28 that's refreshing

2:28 hiredman: somewhat embarressing I did not remember that right away

2:30 Mec: looking in javaland completely slipped past me

2:31 hiredman: it's a big place

2:31 the kingdom of nouns

2:33 slashus2: Is something like indexof going to be in the core for vectors?

2:33 and or sequences in general

2:34 hiredman: why would it need to be?

2:34 it is already there

2:35 I imagine we just need a big honking like to the javadoc for Collections

2:36 ~jdoc java.util.Collection

2:36 link

2:40 heanol: ~clojurebot

2:40 clojurebot: clojurebot is amazing

2:40 heanol: hehe

2:40 are there any sources for the bot?

2:40 hiredman: clojurebot: where are you?

2:40 clojurebot: http://github.com/hiredman/clojurebot/tree/master

2:41 heanol: thanks

2:41 slashus2: hiredman: Aren't things like "count" alternatives for the .length in a collection?

2:42 hiredman: ~def count

2:42 slashus2: I am looking at the source code. It doesn't use .length I see.

2:43 hiredman: my internet is so slow

2:43 still waiting for that to load

2:44 slashus2: I am looking at the count method in RT

2:44 hiredman: I am headed there

2:44 slashus2: It kind of unifies the different length sizeOf getLength things.

2:45 hiredman: hah

2:45 google code thinks this file is under the bsd license

2:48 I guess that is the reason for count

2:48 slashus2: Things were the api is not consistent on the java side may give incentive to cook something up in RT. That may not be the case with indexOf.

3:04 Raynes: Mec: I just got a bit of your can't-spell-for-shit blues. There is no matching method .setVisable in swing ;)

4:59 Lau_of_DK: Hey everybody

7:05 Im running a websolution out of compojure/jetty as a servlet - Anyway to force the content-type in the header to be text/html instead of text-plain ?

7:15 I got it, nvm

7:47 Mec: Raynes: what's the actual method?

8:16 Chouser: rhickey: welcome back

8:17 rhickey: Chouser: thanks - did you hold down the fort?

8:17 Chouser: nope, no need. The bench keeps getting deeper.

8:17 rhickey: that's great

8:18 QCon was awesome

8:18 Chouser: I didn't realize you had several talks until the play-by-play on twitter.

8:19 rhickey: yeah, the second talk was a new one - it went pretty well:

8:19 http://olabini.com/blog/2009/03/qcon-london-thursday/

8:19 Mec: hmm not and nil? seem identical, do they have an oppisite

8:20 Chouser: not and nil? return different values for an arg of false

8:22 Lau_of_DK: "rich spent alot of time talking about state" Hmm, sounds familiar :)

8:22 Mec: true enough chouser

8:23 rhickey: The state talk was the best formulation of some of the key ideas of Clojure I've come up with so far - I'll be including it in my ILC tutorial Sunday

8:23 Lau_of_DK: ILC?

8:24 rhickey: http://www.international-lisp-conference.org/2009/index

8:24 Lau_of_DK: Oh that one - This talk you gave has some interesting slides, but is the talk itself available somewhere?

8:25 RE ILC, cool man, you'll be speaking with Gerald Jay Sussman :D

8:25 Holcxjo: rhickey: Thanks for the talk on Thu evening -- I tried to talk to you in the pub afterwards but you were gone all of a sudden

8:25 rhickey: QCon records everything, but they dribble them out over time - I had two talks and an interview recorded

8:25 Lau_of_DK: k

8:26 Mec: any chance of screencasts on your recent talks?

8:26 rhickey: Holcxjo: yeah, I followed some people upstairs, but the group split

8:26 Mec: they'll come to the InfoQ site over time

8:27 Lau_of_DK: Sussman is a great speaker, I'm psyched to see his talk

8:27 Mec: excellent

8:28 Lau_of_DK: rhickey, I can very well image *jealous*

8:28 :)

8:28 rhickey: I spent a couple of hours in a pub in a fascinating conversation with Joe Armstrong (Erlang)

8:28 Lau_of_DK: s/image/imagine

8:28 cool- Anything interesting come out of it ?

8:29 rhickey: Met also a couple of other Erlangers - Steve Vinoski and Ulf Wiger - very nice guys and receptive to Clojure

8:30 Lots of other really interesting people at the conference as well

8:31 This is probably the best exposure a Lisp has had at an industry conference in a long time

8:35 Lau_of_DK: Sounds very cool

8:35 Guess you've hit the bigtime now :)

8:36 A little disappointing maybe, that you were in London and didnt stop by DK, but we can forgive

8:36 rhickey: Lau_of_DK: not quite :)

8:36 Lau_of_DK: no?

8:40 rhickey: Lau_of_DK: there was a passing mention by the organizers of http://jaoo.dk/aarhus-2009/

8:50 Lau_of_DK: I haven't heard of that before, but if you decide to show up, please keep me posted

9:35 Mec: can you (apply recur list)?

9:36 Chouser: no, recur is a special form

9:36 Mec: i suppose i can just destructure the binding

9:42 Chouser: Compiler$FooExpr classes are very ... mutable.

9:55 keithb: Is there a difference between the meanings of ; and ;; as comment indicators? I've seen both used.

9:55 gnuvince: keithb: it's more of a convention: ; is used inline, ;; is usuall on its own line

9:55 ;; example function

9:56 fogus: I think ;; just makes things stand out a little better

9:56 gnuvince: (defn foo []

9:56 (+ 3 4)) ; greatest operation ever

9:56 keithb: gnuvince: fogus: Thanks.

9:58 arbscht: ;; typically gets indented as well

9:58 (defn foo []

9:59 ;; greatest operation follows

9:59 (+ 3 4))

9:59 Chouser: Is this a convention borrowed from an earlier lisp?

9:59 arbscht: from emacs :)

10:23 rhickey: Chouser: don't emulate that mutability. Mostly it's just for the intimately-related Parser class

10:24 Chouser: rhickey: some of it will be difficult to avoid, like parent pointers going from fnmethods on up.

10:24 AWizzArd: clojurebot: max people

10:24 clojurebot: max people is 149

10:25 AWizzArd: uh, it was 162 before

10:25 Chouser: clojurebot forgot some things

10:25 AWizzArd: I see

10:26 rhickey: Chouser: I'd like to see where it's not possible - one thing for sure is that I avoided passing some things up/down that now I would readily do rather than use the dynamic vars

10:32 Mec: is there a way to do default values for function args, without arity?

10:33 AWizzArd: What means "without arity"?

10:33 Mec: overloading

10:33 AWizzArd: Should not every function have an arity? Even if it is 0? (in that case it is a constant or has side effects)

10:34 Mec: arity is the number of args

10:34 AWizzArd: so each function must have an arity

10:34 Mec: (defn f ([x] x) ([x y] (+ x y))

10:34 AWizzArd: anyway, you could make the function take hashmaps

10:35 Mec: hmm

10:35 AWizzArd: hashmaps are the idiomatic way to do this in Clojure

10:36 you can call (f {:x 10 :y 20}) or just (f {:x 10})

10:37 and it will (merge {:y (:x arg)} x) inside the function f

10:38 if x does not contain an {:y value} it will use the {:x val} in x

10:38 Mec: ah that could work

10:40 AWizzArd: oh, this should have been (merge {:y (:x arg)} arg) of course

10:41 But really, if this is just for such a small thing such as your f, then I suggest to overload f.

10:50 Mec: isnt there some function like append that lets you put 2 lists together

10:51 dliebke: ,(conj {:a 1} {:b 2})

10:51 clojurebot: {:b 2, :a 1}

10:51 Mec: ah concat

11:09 hiredman: clojurebot: destructuring

11:09 clojurebot: destructuring is http://clojure.org/special_forms#let

11:12 hiredman: ,((fn [{:keys [a b c] :or {c 10}}] [a b c]) {:a 1 :b 2 :c 3})

11:12 clojurebot: [1 2 3]

11:12 hiredman: ,((fn [{:keys [a b c] :or {c 10}}] [a b c]) {:a 1 :b 2})

11:12 clojurebot: [1 2 10]

11:19 AWizzArd: clojurebot: max people is 162

11:19 clojurebot: Ok.

11:26 danlarkin: AWizzArd: *gasp*!

11:26 AWizzArd: hmm?

11:41 danlarkin: AWizzArd: you interfered with the max people count

11:41 AWizzArd: I resetted it to the last known entry.

11:41 It forgot some information.

11:44 hiredman: the machine crashed, and somehow the file was emptied, and I did not notice till the empty file copied over the backup

11:45 Mec: is there some way to (apply f list val)

11:46 AWizzArd: yes: (apply f list val)

11:46 hiredman: what do you want that to do?

11:46 Mec: (apply f '(1 2 3) 4) -> (f 1 2 3 4)

11:46 hiredman: ah

11:46 AWizzArd: is val a list/vector?

11:46 do (list val)

11:46 or [val]

11:46 (apply + [1 2 3] [4])

11:46 ,(apply + [1 2 3] [4])

11:46 clojurebot: java.lang.ClassCastException: clojure.lang.LazilyPersistentVector cannot be cast to java.lang.Number

11:47 AWizzArd: great

11:47 Mec: ,(apply list '(1 2 3) [5])

11:47 clojurebot: ((1 2 3) 5)

11:47 AWizzArd: ,(apply + 1 2 3 [4])

11:47 clojurebot: 10

11:48 hiredman: ,(apply (comp (partial apply conj) reverse list) [1 2 3] 4)

11:48 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

11:48 hiredman: hmmm

11:48 ,(apply (comp (partial apply conj) list) [1 2 3] 4)

11:48 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

11:48 hiredman: ah

11:48 ,((comp (partial apply conj) list) [1 2 3] 4)

11:48 clojurebot: [1 2 3 4]

11:49 Mec: ,(apply + (concat '(1 2 3) [4])))

11:49 clojurebot: 10

11:49 hiredman: hmmm

11:50 Mec: all ugly :x

11:50 hiredman: ,(conj [1 2 3] 4)

11:50 clojurebot: [1 2 3 4]

11:50 hiredman: ,(apply + (conj [1 2 3] 4))

11:50 clojurebot: 10

11:51 Mec: that only works if it's a vector, a list gets prepended

11:51 AWizzArd: of course

11:51 dnolen: is the Clojure equivalent of the atom predicate in Common Lisp (not (seq? x)) ?

11:52 Chousuke: hmm

11:52 replaca: Chouser: The ;,;;,;;; convention is not tied to emacs but is traditional predating even common lisp. Emacs "encourages" it, though, by auto-indenting comments based on the number of semicolons

11:52 Chousuke: ,(not (seq? [1 2 3]))

11:52 clojurebot: true

11:52 Chousuke: so not quite :/

11:53 ,(not (coll? [1 2 3]))

11:53 clojurebot: false

11:53 Chouser: (not (coll? x)) is closer

11:53 yeah

11:53 replaca: ah, thanks.

11:55 dnolen: Chouser: thx

11:56 what would be a good name for such a function since Clojure has it's own idea of atom?

11:58 hiredman: not-a-seq?

11:58 not-a-coll?

11:58 (def not-a-coll? (comp not coll?))

11:59 dnolen: that's short and sweet like (atom x) :), I've been converting snippets of Common Lisp in my exploration of Clojure.

12:01 AWizzArd: in CL: (atom (vector 1 2 3)) ==> T

12:02 dnolen: interesting so (not (seq? x)) is better AWizzArd?

12:02 AWizzArd: the HyperSpec defines: (defparameter x (make-instance 'interface-1))

12:02 (defparameter dp (slot-value x 'dis-pai))

12:02 oops

12:03 atom n. any object that is not a cons.

12:03 this is the right thing :)

12:04 So, the closest thing would indeed be (not (seq? x))

12:04 hiredman: ~hyperspec is not applicable

12:04 clojurebot: In Ordnung

12:04 Chousuke: hmm

12:05 AWizzArd: hiredman: that makes not too much sense. Of course Clojure is different, but it was designed with (Common Lisp) in mind and took huge amounts of the experience of it.

12:05 hiredman: ~what does the hyperspec say about clojure's vectors?

12:05 clojurebot: hyperspec is not applicable

12:05 AWizzArd: I think it makes sense to keep some of the vocabulary that is used since a few decades.

12:05 hiredman: ~what does the hyperspec say about java objects?

12:05 clojurebot: hyperspec is not applicable

12:06 hiredman: anyway

12:06 Chousuke: AWizzArd: the CL meaning of atom is not very useful in a Clojure context :)

12:07 hiredman: clojure has no cons cells, so it's all atoms

12:07 dnolen: Chousuke: it is if your porting CL, I think it does, macros produce seqs for example

12:07 checking for not-seq? is useful

12:08 Chouser: I rarely use coll? and even more rarely (not (coll? x)), but both a *far* more common than seq? or (not (seq? x))

12:08 Chousuke: dnolen: I was talking about the "not a cons" definition of atom

12:08 hiredman: dnolen: there is nothing stopping a macro from return something that is not a seq

12:08 AWizzArd: Chousuke: right, I agree. One could still argue that the verb "consing" still makes sense.

12:09 Chousuke: Chouser: the more common form of (seq?) is probably (if (seq foo))

12:09 AWizzArd: well, yeah. but cons is not that common in clojure :)

12:09 dnolen: hiredman: syntax backquote returns seqs, that's probably the most common form for macroexpansion.

12:09 AWizzArd: Chousuke: if the goal is to get the close to the original behaviour then (atom? some-vector) should return true.

12:09 hiredman: dnolen: sure, but:there is nothing stopping a macro from return something that is not a seq

12:09 Chousuke: AWizzArd: though perhaps full laziness will make it more common.

12:10 AWizzArd: what do you mean?

12:10 dnolen: hiredman: and then that's OK ;)

12:10 hiredman: ~def future-call

12:10 Chousuke: AWizzArd: conj is more common that cons :)

12:10 than*

12:10 Chouser: Chousuke: right, but of course 'seq' is not 'seq?'

12:10 hiredman: there are plenty of macros that actually return a java object

12:10 AWizzArd: yes, I mean with this full lazyness thing

12:10 Chousuke: AWizzArd: clojure.org/lazy

12:10 ~laziness

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

12:11 Chousuke: hmm

12:11 ~lazy

12:11 clojurebot: lazy is hard

12:11 Chousuke: :(

12:11 As I understand it, with the fully lazy stuff, lazy-cons will get replaced by cons and lazy-seq

12:12 or has been replaced.

12:12 :P

12:12 depending on your view.

12:12 hiredman: will?

12:12 it's already happened

12:12 Chousuke: yeah, but not in a release :/

12:12 unless there was a new one I missed.

12:13 cgrand: rhickey: just found a bug in my patch to proxy, line 170 should read "(if (or (considered sig)" and not "(if (or (considered mk)"

12:16 AWizzArd: I think lazy-cons is not in svn anymore?

12:19 hiredman: ,'lazy-cons

12:19 clojurebot: lazy-cons

12:19 hiredman: ,`lazy-cons

12:19 clojurebot: sandbox/lazy-cons

12:19 hiredman: sure ain't

12:24 AWizzArd: ,(/ 1M 3)

12:24 clojurebot: java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

12:35 AWizzArd: ,(.divide 1M 3M 10 BigDecimal/ROUND_CEILING)

12:35 clojurebot: 0.3333333334M

12:48 slashus2: ,(doc with-precision)

12:48 clojurebot: "([precision & exprs]); Sets the precision and rounding mode to be used for BigDecimal operations. Usage: (with-precision 10 (/ 1M 3)) or: (with-precision 10 :rounding HALF_DOWN (/ 1M 3)) The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP."

12:48 slashus2: ,(with-precision 10 (/ 1M 3))

12:48 clojurebot: 0.3333333333M

12:51 slashus2: I am getting this strange error in my repl (with-precision 10 (/ 1M 3)) java.lang.NoClassDefFoundError: clojure/core$binding__3596$var_ize__3598 (NO_SOURCE_FILE:32)

12:53 gnuvince: if I find Clojure being significantly slower than Java (factor of b

12:53 (factor of 8), and that I know I don't have reflexion calls, where else would be a good place to look for?

12:57 whidden: gnuvince: are you doing a lot of mathematical operations?

13:00 gnuvince: whidden: not a lot, no.

13:01 whidden: my code: http://bitbucket.org/gnuvince/clj-starcraft/src/

13:03 keithb: gnuvince: VisualVM might be helpful.

13:03 whidden: gnuvince: have you profiled the code with a profiler?

13:03 gnuvince: culprit(s) will probably be un src/starcraft/replay/unpack.clj and parser.clj

13:04 keithb: gnuvince: It's a free profiler for Java.

13:04 gnuvince: whidden: I ran with -Xprof

13:04 Tells me about the functions I expected to see

13:04 I started -Xrunhprof:cpu=times

13:04 But that takes forever to run, so I won't be able to give you any numbers for at least 15 minutes

13:08 keithb: gnuvince: In this code: (apply str (take-while #(not= % \u0000) bytes)))), is it a very large number of bytes? If so, does str do string concatenation or does it use a StringBuffer or such? The former could result in a huge number of objects, and possibly take much longer.

13:08 whidden: gnuvinced: i'd second the suggestion to use VisualVM - I think that would help to sort through the numbers

13:09 gnuvince: No GUI here though

13:09 I'll need to try it at home.

13:09 hiredman: ~def str

13:10 gnuvince: keithb: never more than 32 bytes. However, (apply str) is the "normal way" to concatenate strings and it's pretty efficient (uses a StringBuilder internally and by using apply, uses only one instead of n if reduce was used)

13:12 whidden: gnuvince: I've found that doing speculation refactoring without had profile data is mostly useless. It's been my experience that the places you spend a lot of time are places you think safe/cold.

13:12 keithb: gnuvince: Thanks.

13:13 * hotcore[A] is now away - Reason : Auto-Away (Away from Keyboard)

13:13 gnuvince: whidden: my experience too: I dramatically improved performance after I found that reflexion was taking a huge amount of time

13:14 But now, I am not sure where to look except maybe try and make the code "lower level"

13:14 whidden: gnuvince: My quick cursorary glance, with my somewhat novice Clojure eyes, didn't see any egregious erors.

13:14 gnuvince: -Xrunhprof still running...

13:16 Chouser: after reflection the next most common slow spots are boxing and unboxing in tight loops

13:16 I haven't looked at your code, though, so I can't say it applies in this case.

13:17 gnuvince: How expensive is destructuring versus extracting elements manually? I'd say exactly the same?

13:19 Chouser: you can look at the macroexpanded code -- generally has calls to nth for each arg

13:19 hiredman: I recall someone mentioning it has a slow down

13:19 but that was many months ago

13:20 danlarkin: it was a little slower in my experience

13:20 but that was over thousands of function calls

13:21 Raynes: Mec: .setVisible

13:21 danlarkin: so maybe don't use it in a tight loop, but otherwise it's unnoticeable

13:21 Raynes: I know, delayed response. Just woke up.

13:24 On a brighter note, I know how to spell 'visible' now.

13:26 pjstadig: so i have agents working with TC

13:27 the next thing is clojure.lang.Atom

13:27 hiredman: Nice

13:27 Chouser: pjstadig: each 'send' may go off to a different host?

13:29 hiredman: that would be interesting

13:29 pjstadig: hehe

13:29 good question

13:29 the agent has a queue

13:30 so i would guess that the first VM to pop the queue would do the work

13:30 there would obviously be one thread pool per VM, since threads are a non portable object

13:31 i've only gotten them to work preliminarily

13:31 Chouser: ok

13:31 pjstadig: i can (send *a* + 1) in one vm

13:31 and see @*a* => 2 in the other

13:32 danlarkin: pjstadig: I'm really excited about this

13:32 pjstadig: i had to basically replace the AtomicReference uses to get them to work

13:34 i had to add some synchronized blocks, so i'm not sure that I haven't changed some semantics

13:34 i'm just trying to get it working first, then to test and fix

13:34 danlarkin: me too

13:35 does anyone have some Java concurrency foo?

13:35 i need to rewrite Atom to not use a java.util.concurrent.AtomicReference

13:36 hiredman: sounds scary

13:36 pjstadig: I'm guessing I can use a wait with a very small timeout?

13:36 hiredman: ~jdoc java.util.concurrent.AtomicReference

13:36 pjstadig: then kick back if the thread didn't get it's job done

13:36 hiredman: :(

13:36 404

13:36 pjstadig: 404 FAIL

13:36 er

13:37 maybe i had the class name wronge

13:37 hiredman: nah

13:37 pjstadig: ~jdoc java.util.concurrent.atomic.AtomicReference

13:37 hiredman: it ah

13:38 ~I forgive you

13:38 clojurebot: I don't understand.

13:38 danlarkin: ~clojurebot couldn't find the right javadoc URL so hiredman got mad and then suddenly...

13:38 clojurebot: hiredman is slightly retarded

13:39 danlarkin: Nooooo

13:39 pjstadig: hehe

13:39 hiredman: :(

13:41 pjstadig: actually i guess i could just use a synchronized block to simulate compareAndSet

13:51 * gnuvince is back (had to fix somebody's PC at work :(

13:51 gnuvince: and -Xrunhprof is still running

13:57 rhickey: pjstadig: you could just use synchronized - the reason atoms don't is that you can deadlock on nested swap!s

13:59 blbrown_lt: gnuvince, what version of the jdk are you running. I had issues getting runhprof to work with jdk5. Just a fyi

14:01 gnuvince: blbrown_lt: sun-jvm-6 from Ubuntu Hardy IIRC

14:01 java version "1.6.0_07"

14:02 blbrown_lt: OK, that should work fine. With 'hat' for example

14:02 gnuvince: hat?

14:02 blbrown_lt: if you run Xrunhprof, you may also want to use the heap analysis tool. to see the results of hprof

14:03 gnuvince: Is that a command line argument?

14:04 blbrown_lt: try jhat

14:06 gnuvince, a small blog entry on how I use hprof. search for the term if you dont want to read. http://berlinbrowndev.blogspot.com/2008/12/basic-tools-for-monitoring-garbage.html

14:08 pjstadig: rhickey: so there's no deadlock problem for clojure.lang.Atom?

14:08 rhickey: pjstadig: nope

14:08 nor for any other Clojure reference type

14:09 I'm working on a mutex reference type, which will avoid deadlock by constraining nesting

14:10 gnuvince: rhickey: hi, how did the UK trip go?

14:10 rhickey: gnuvince: it was awesome

14:10 gnuvince: rhickey: cool! :)

14:12 blbrown_lt: thanks, bookmarked.

14:12 rhickey: I think ILC is next week, isn't it?

14:12 danlarkin: blbrown_lt: same, this is a useful writeup, thanks

14:12 blbrown_lt: sorry I keep bringing this up. does it make any sense to create a clojure based framework that uses springmvc and hibernate. I like the libraries and have used them for several years. And think for the business layer, clojure could help. integrating spring and hibernate. But then again, maybe it is time to completely start from scratch hmm. For example, I also wouldnt mind coming up with a new server pages framework (e.g. not jsp)

14:12 . I hate hjsp

14:12 rhickey: gnuvince: yes

14:13 blbrown_lt: danlarkin, no prob. if you have websphere it even makes more sense

14:13 gnuvince: rhickey: good luck there, hope they're not like on cll in real life :)

14:13 danlarkin: blbrown_lt: you can help me develop madison...

14:14 rhickey: gnuvince: I spoke to Boston Lisp in the fall and they were a great audience, I expect the same, plus some more Clojure folks too

14:14 blbrown_lt: danlarkin, what is madison

14:14 pjstadig: ~clabango

14:14 clojurebot: http://www.clabango.com/

14:14 blbrown_lt: plus, I am kind of too headstrong to work with others

14:15 danlarkin: blbrown_lt: http://github.com/danlarkin/madison/tree/master

14:16 pjstadig: sweet!

14:16 blbrown_lt: danlarkin, I am assuming it is a web framework

14:16 danlarkin: blbrown_lt: eahup it is

14:17 yet another unnecessary web framework

14:18 pjstadig: Yauwf

14:20 hiredman: clojurebot: Yawfie?

14:20 clojurebot: Yawfie is danlarkin's port of django to clojure

14:21 hiredman: :(

14:21 clojurebot: forget Yawfie

14:21 clojurebot: I forgot Yawfie

14:22 hiredman: clojurebot: madison?

14:22 clojurebot: Excuse me?

14:22 hiredman: clojurebot: madison is http://github.com/danlarkin/madison/tree/master

14:22 clojurebot: Roger.

14:24 Chouser: rhickey: an odd thing about this is that I have much more of Clojure available in the compiler now than exists at the top of core.clj

14:25 it's be easier to make fn a 'special form' that expands to an instance form internally and analyzes that, than to try to write a fn macro at the top of core.clj

14:25 s/it's/it would/

14:28 kefka`: In Clojure, can purely functional calculations be assumed to be properly parallelized?

14:29 blbrown_lt: danlarkin, I wouldn't say it is unncessary. There are still things broken with most j2ee web frameworks. And there aren't that many popular ones or that are different.

14:29 danlarkin: kefka: no...

14:29 blbrown_lt: danlarkin, do you use any third party library. For example, in my approach, I want to use a couple of common existing frameworks

14:30 danlarkin: blbrown_lt: well it's definitely nowhere near complete yet, but no I'm not using like Hibernate or anything

14:30 I am using a few clojure libraries though

14:31 kefka: danlarkin: Ok, so in order to ensure parallelism, should I be spwaning threads or using agents?

14:32 danlarkin: kefka: there're a few ways... agents, futures, pmap...

14:32 Chouser: clojure.parallel

14:33 danlarkin: pvalues

14:34 netytan: Good day ladies and gentlemen - could someone comment on the implementation of multimethods in Clojure. My contention is that they're implemented in the same way as CLs or Dylans generic functions. Is this factual?

14:35 More importantly, do they have the same semantics.

14:35 hiredman: who are you contending with?

14:36 cmvkk_: for example, in clojure's multimethods you can define your own dispatch function, where in CL it just dispatches on type.

14:37 kefka: Where are futures discussed? Also, if I'm making a function call (f X Y Z) and want the evaluations of X, Y, Z to be done in parallel, what's the idiomatic/correct way of doing so?

14:38 netytan: hiredman: I'm engaged in a discussion with a friend and I don't like to lie.

14:38 hiredman: ,(doc pvalues)

14:38 clojurebot: "([& exprs]); Returns a lazy sequence of the values of the exprs, which are evaluated in parallel"

14:38 danlarkin: (apply f (pvalues X Y Z))

14:38 netytan: cmvkk_: I'm sure that you can waggle it. In any case don't let the CL guys year you say that CL can't do something :).

14:39 cmvkk_: heh

14:40 keithb: I know that proxy creates an instance of a subclass of a Java class, but can I create a subclass in Clojure, for the purpose of creating multiple instances of that subclass?

14:40 Mec: anyone know of a fast trick to add the digits of a number together?

14:40 cmvkk_: keithb, maybe using gen-class

14:40 keithb: (doc gen-class)

14:40 clojurebot: When compiling, generates compiled bytecode for a class with the given package-qualified :name (which, as all names in these parameters, can be a string or symbol), and writes the .class file to the *compile-path* directory. When not compiling, does nothing. The gen-class construct contains no implementation, as the implementation will be dynamically sought by the generated class in functions in an implementing Clojure na

14:40 p_l: cmvkk_: AFAIK you can change the way multimethods are dispatched with MOP :D

14:41 keithb: cmvkk_: Thanks.

14:41 kefka: embarrassed on pvalues; should have looked that up before asking. Sorry.

14:42 hiredman: keithb: I believe proxy makes one subclass per class (possibly class/interface combination?) and then after that just makes instances of that one subclass

14:42 kefka: ,(doc future)

14:42 Chouser: keithb: a class created by proxy is created at compile time and reused each time proxy is called for the same set of parent classes.

14:42 clojurebot: "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."

14:42 danlarkin: kefka: don't worry about it, that's what we're here for :)

14:43 Chouser: maybe pvalues could be implemented on a seq of futures now, instead of via pmap.

14:44 hiredman: pmap is a seq of futures

14:44 kefka: I'm about to update to current version and pull clojure-contrib for something almost in production... anything I should be worried about?

14:45 Chouser: hiredman: oh. indeed it is. thanks. :-)

14:45 hiredman: uh, have you crossed the lazy barrier already?

14:45 kefka: I'm about to cross it.

14:45 ,(doc rest)

14:45 clojurebot: "([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."

14:45 hiredman: it looks like pvalues uses map, not pmap

14:45 keithb: Chouser: Sorry, I may have asked you this before, but in the code at http://gist.github.com/80000, if I call it multiple times with different behavior arguments, the values returned will all be instances of the same class?

14:45 kefka: ,(doc next)

14:45 clojurebot: "([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."

14:45 kefka: ,(seq nil)

14:45 clojurebot: nil

14:46 kefka: ,(next [1])

14:46 clojurebot: nil

14:46 kefka: ,(rest [1])

14:46 clojurebot: ()

14:46 kefka: I see that change. It used to be that (rest [1]) was nil and thus logically false.

14:46 Chouser: keithb: yes

14:47 keithb: try a couple and compare their class names.

14:47 Mec: is that just to kind of force people to use next?

14:47 kefka: So the behavior of 'rest has changed? Any other differences?

14:47 triddell: For you current (or future ;) Ubuntu/Emacs uses out there I've updated my tutorial: http://riddell.us/tutorial/slime_swank/slime_swank.html

14:47 hiredman: keithb: have you read the lazy page on clojure.org?

14:48 triddell: I broke it into three pieces now. One for basic clojure, one for emacs and one for slime/swank.

14:48 hiredman: keithb: http://clojure.org/lazy

14:49 pjstadig: cool

14:49 marklar: triddell: thanks, I used that to get setup the first time :)

14:49 triddell: I plan to add some tutorials on git/egg and maybe muse and android in the future

14:49 Mec: any thoughts on combining :while and :when in a for?

14:49 keithb: hiredman: No, but I will. ;)

14:49 Chouser: Mec: go for it

14:49 pjstadig: triddell: any thoughts about using M-x clojure-install to set everything up?

14:50 hiredman: it has a section on "porting"

14:50 triddell: marklar: your welcome... hope it helped... got a bit out of date

14:50 Mec: Chouser: lol, i mean is it possible, i dont think im up to tackling that yet

14:50 Chouser: Mec: there has been a subtle change to the sematics when you have both on the same loop-part

14:50 marklar: triddell: it definitely helped, thanks

14:51 Chouser: Mec: so make sure you know if you're using a pre-1320 version or not

14:52 Mec: hmm is there a function that returns the version

14:52 hiredman: nope

14:52 :(

14:52 danlarkin: Mec: frequently requested, but no

14:52 Mec: let me see if i can find it

14:52 keithb: hiredman: What is the connection between proxy and lazy? I read the page (skimmed really, a lot was over my head for now), but didn't understand how it applies to my problem.

14:52 triddell: pjstadig: saw that once... have to look a bit more... since the process isn't to bad I think a developer using something like clojure in emacs can benefit from how the pieces work together... I would like to reference a script which would keep this particular setup updated... and maybe I could reference M-x clojure install in the future

14:53 keithb: pjstadig: Paul, is that you? :)

14:53 hiredman: keithb: oh, uh, I meant kefka

14:53 sorry

14:53 keithb: Oh, ok.

14:53 Mec: does it say anywhere in the source code what the version is?

14:53 Chouser: Mec: depends on how you got clojure. downloaded a .jar? git? svn?

14:53 hiredman: clojurebot: appologize for me!

14:53 clojurebot: for is not used often enough

14:53 Mec: clojurebox

14:53 bitbckt: lol

14:54 hiredman: clojurebot: apologize for me!

14:54 clojurebot: mea culpa!

14:54 pjstadig: triddell: it seems like an easy way to get things going, plus M-x clojure-update can help keep you up to date, but you're probably right. it's good to get to know how the tools work together.

14:54 keithb: yeah :)

14:56 triddell: pjstadig: I will look into that... is that available on a fork of clojure-mode?

14:56 pjstadig: or swank-clojure

14:56 Mec: lookjs like i have 1235

14:58 hiredman: r1230

14:58 Chouser: Mec: ok. you can still use :when and :while on the same loop part, but the order in which you give them won't matter

14:58 r1320

14:59 hiredman: whoops

14:59 Chouser: :-)

14:59 Mec: ok

14:59 Chouser: I'm trying to remember ... I thnk the :while is checked first. If that's true, then it checks the :when

14:59 Mec: that's how i'd expect

15:00 Chouser: if the :when and :while are on different loop parts, then they're checked in the order you give them.

15:00 Mec: while is for the whole loop, when is for individual values

15:00 Chouser: in r1320 and on, they're always checked in the order you give them.

15:01 gnuvince: Holy schmoly, -Xrunhprof has been running for nearly 2 hours now

15:01 Mec: from looking at the code it seemed they where in a cond and only one would work

15:02 Chouser: Mec: oh!

15:02 Mec: no, you're right. :-(

15:02 Mec: well poo

15:02 Chouser: sorry, I'm forgetting. I think they both worked on doseq

15:03 Mec: hmm, best way to filter out nil then?

15:04 Chouser: hm

15:04 Mec: (filter (compliment nil?) list) i guess

15:04 hiredman: (filter identity ...) or (remove nil ...)

15:04 Chouser: ,(for [i [1 3 5 7 8 9 10] :while (odd? i) :when (> i 3)] i)

15:04 clojurebot: (5 7)

15:04 Chouser: does that not work for you?

15:05 Mec: remove says it returns when pred is false, does that mean it will drop it will drop all but nil?

15:05 oh nvm

15:05 didnt parse that correctly

15:06 hiredman: uh, that remove call maybe wrong

15:06 I use (filter identity ...)

15:06 Chouser: Mec: did you try the (for ...) example I just posted?

15:06 hiredman: so I dunno how remove works

15:06 pjstadig: triddell: its in clojure-mode

15:06 gnuvince: -Xrunhprof has been running for 2 hours now; is there a problem?

15:06 pjstadig: and i think it's in the master branch

15:06 Mec: it gives me the same result as clojurebot

15:07 Chouser: Mec: great -- looks like you can combine them then.

15:07 Mec: weird but yay

15:08 Chouser: but as I said, they'll always go in that order.

15:08 ,(for [i [1 nil 3 5 nil 7 8 9 10] :when i :while (odd? i)] i)

15:08 clojurebot: (1 3 5 7)

15:08 Chouser: in your version, that probably throws a NPE

15:09 Mec: shouldnt it stop on 8?

15:09 ya nill pointer

15:09 err it does

15:09 wow im just out of it right now

15:11 kefka: ,(doc clojure/contrib/fcase)

15:11 clojurebot: java.lang.Exception: Unable to resolve var: clojure/contrib/fcase in this context

15:11 kefka: ,(doc clojure.contrib/fcase)

15:11 clojurebot: java.lang.Exception: Unable to resolve var: clojure.contrib/fcase in this context

15:11 kefka: ,(doc clojure.contrib.fcase)

15:11 clojurebot: java.lang.Exception: Unable to resolve var: clojure.contrib.fcase in this context

15:12 danlarkin: kefka: you know, you can call doc from your local command line too :)

15:12 Mec: lol

15:12 hiredman: clojurebot also responds to privmsgs

15:12 pjstadig: clojurebot can also be PM'ed

15:13 kefka: danlarkin: I know, but I wanted to know if I had clojure-contrib properly installed.

15:13 It wasn't working at my local command line. I wanted to see if it works here.

15:13 hiredman: you need to (require 'clojure.contrib.fcase) first

15:14 eevar_: best way to read all contents from a java.io.Reader into a string?

15:14 * hiredman does some hand wavy stuff

15:14 kefka: hiredman: Ah. Cool. I assume the same's true of clojure.parallel?

15:15 hiredman: and most namespaces don't have docstrings

15:15 and clojurebot's doc lookup may not work with namespaces that do

15:17 * Raynes pokes hiredman with a clojurebot

15:17 hiredman: https://twitter.com/clojurebot/status/1337623633

15:17 I love how the eyes kind of look up towards the tweet

15:19 kefka: When I require 'clojure.parallel, I get a weird error message

15:19 java.lang.ClassNotFoundException: jsr166y.forkjoin.ParallelArray (parallel.clj:0)

15:19 hiredman: correct

15:20 the location of some classes has changed in jsr166y have changed

15:20 kefka: Do I need to require something else before clojure.parallel?

15:20 hiredman: and clojure.parallel has not been updated

15:20 kefka: What is jsr166y?

15:20 hiredman: http://paste.lisp.org/display/77047

15:20 oh

15:21 Well

15:21 you need the jsr166y.jar

15:21 pjstadig: rhickey: i figured out the random NPEs i was getting from PersistentHashMap$BitmapIndexedNode

15:21 not a bug in PHM, but TC had a problem with calling clone() on an array

15:22 that's done several places in the persistent structures

15:22 hiredman: kefka: see http://clojure.org/other_libraries

15:22 pjstadig: i changed them to new Object[_]; System.arraycopy()

15:23 is there an advantage to using clone() instead of creating and copying?

15:26 Chouser: anyone here using cl-format?

15:27 Lau_of_DK: Not since I left cl...

15:27 Chouser: no, I mean cl-format for Clojure.

15:27 Lau_of_DK: oh :) no

15:27 Chouser: http://github.com/tomfaulhaber/cl-format/tree/master

15:27 pjstadig: wise guy

15:28 Lau_of_DK: Is that based on the pprint you did Chris ?

15:28 Chouser: no

15:28 gnuvince: ~seen blbrown_lt

15:28 clojurebot: blbrown_lt was last seen in #clojure, 58 minutes ago saying: danlarkin, do you use any third party library. For example, in my approach, I want to use a couple of common existing frameworks

15:28 Chouser: I'm trying to use it, but so far it's too smart for me.

15:28 blbrown_lt: gnuvince, yea

15:29 Lau_of_DK: Hmm, that sounds alarming :)

15:29 gnuvince: blbrown_lt: is the output of -Xrunhprof:cpu=times reliable?

15:29 Chouser: the compiled .jar fails, the git clone requires that it be compiled, and I can't figure out how to compile the git clone.

15:30 gnuvince: Cause the numbers are... weird

15:30 blbrown_lt: gnuvince, I would hope so, but I normally haven't used that statistic. Are you running on a decent machine

15:31 gnuvince: blbrown_lt: yeah

15:31 lisppaste8: gnuvince pasted "Profile output (top 20 only)" at http://paste.lisp.org/display/77121

15:32 kefka: hiredman: so the change I need to make to use clojure.parallel is in the paste you sent me, and that's a change to parallel.clj?

15:32 pjstadig: starcraft.replay.parse/parse-buffer and starcraft.replay.parse/read-field-aux look like the winners

15:33 gnuvince: Yeah

15:33 I'm a bit confused

15:33 why are the first two methods taking so long?

15:33 Especially when they're called only 9 times

15:34 blbrown_lt: gnuvince, http://stackoverflow.com/questions/375439/java-hprof-question I havent used that aspect of the profiling so I would be pretending if I knew. But, I would think it makes sense

15:34 ask rhickey maybe he could run hprof also

15:34 hiredman: kefka: I believe so, I have not used it

15:35 kefka: Now I get "java.lang.ClassNotFoundException: extra166y.ParallelArray (parallel.clj:0)"

15:36 Never mind. Embarrassing classpath mistake.

15:36 pjstadig: gnuvince: well i don't know, but maybe it was a fluke

15:37 maybe that's why it took so long, something went screwy?

15:39 blbrown_lt: gnuvince, this may help also. http://java.sun.com/developer/technicalArticles/Programming/HPROF.html

15:39 gnuvince: pjstadig: I don't think it was a fluke, the performance of the site has been pretty much the same for a while now.

15:39 Lau_of_DK: Compojure guys! If I want to attach an onchange event to a drop-down, how do I do that ?

15:39 gnuvince: (I just happened to test a Java version this morning, and it ran about 8x faster)

15:40 kefka: Ok. Still I'm getting the same error.

15:43 The error being "java.lang.ClassNotFoundException: extra166y.ParallelArray (parallel.clj:0)

15:43 when I try to require clojure.parallel

15:44 hiredman: do you have all the right jars?

15:45 http://gee.cs.oswego.edu/dl/concurrency-interest/

15:45 kefka: I have jsr166y.jar, clojure.jar, and clojure-contrib.jar in my classpath

15:46 hiredman: there is also a extra166y.jar

15:46 kefka: Ok. It looks like I need extra166y.jar and possibly others. Thanks.

15:48 hiredman: it's working now. Thanks.

15:51 hoeck: Chouser: just got cl-format working here, it's nice

15:52 Chouser: hoeck: you're using this jar, or something else? http://github.com/tomfaulhaber/cl-format/raw/master/release/cl-format.jar

15:52 hoeck: Chouser: I had to set the clojure-jar property in the build.xml manually and then just used ant to build the jar

15:53 Chouser: I cloned the repository and built my own jar

15:54 Chouser: ok, that's what I've done too.

15:54 I had a typo in my clojure-jar property that stumped me for a while.

15:54 but now it builds, and I get a cl-format.jar

15:55 but when I put that in my classpath, I get:

15:55 user=> (use 'com.infolace.format)

15:55 java.lang.NoClassDefFoundError: clojure/lang/RT (format.clj:0)

15:57 ok, I just got it to work, by putting cl-format.jar directly in my -cp option, instead of copying it to one of my java.ext.dirs

15:57 this I do not like.

15:58 slashus2: Why does pvalues use a syntax quote on fn instead of ' ?

15:58 hoeck: what is a java.ext.dir?

15:59 * hoeck used add-classpath

15:59 hiredman: if you figure out why some things don't work well with java.ext.dir it would be interesting to know

15:59 hoeck: don't

15:59 ~add-classpath

15:59 clojurebot: add-classpath is bad, avoid it. I mean it!

15:59 hiredman: ~jar directory

15:59 clojurebot: with java6(jdk1.6) CLASSPATH can contain a "*" so /jar/dir/* will suck in all the jars in the /jar/dir directory, this also works with swank-clojure-extra-classpaths in emacs, alternatively you can use this shell snippet: find .jars/ -type f -name \*.jar -print0|xargs -0|sed "s/ /:/g"

16:00 hiredman: of course that will all confuse people

16:00 who will try and use * like shell expansion

16:00 hoeck: but adding a jar after starting the jvm to a * classpath doesn't seem to work

16:00 hiredman: *sigh*

16:00 hoeck: the solution is "do not use add-classpath"

16:01 Chouser: ok, pprint working. I'll have to look at java.ext.dirs later. Thanks all.

16:01 hoeck: I know

16:01 hiredman: add-classpath is unreliable

16:01 cemerick: rhickey: I'm sure you get notifications and such, but I wanted to raise this regression directly: http://code.google.com/p/clojure/issues/detail?id=98

16:01 hiredman: so don't rely on it

16:02 * hoeck is still too lazy to restart his jvm

16:02 cemerick: I would go spelunking in the gen-class stuff, but I'm completely tied up.

16:02 kotarak: isn't java.ext.dirs also the voodoo thing, one shouldn't use?

16:02 hiredman: kotarak: that has been my experience

16:02 sometimes it doesn't work

16:03 pjstadig: how can you patch a long running JVM with code changes that may necessitate classpath changes?

16:04 walters: pjstadig: one thing you need to understand is the Permgen

16:04 Chouser: what code changes necessitate classpath changes?

16:04 pjstadig: takes away from the dynamic nature of Clojure, me thinks, if you can't dynamically change the classpath

16:04 kotarak: I don't get, what problems people have with their classpath. I have I directory, where I put all jars I want in there. Together with symlinks to local stuff. A starter script adds all that to the CLASSPATH env var and fires up clojure. I never ever had a single problem with this setup.....

16:04 pjstadig: kotarak: we're talking about changing the classpath after the JVM has booted

16:05 Chouser: kotarak: I'm trying to remember why i moved off of that.

16:05 cemerick: pjstadig: as long as you bootstrap your app with a classloader you control (i.e. *not* the bootclassloader), then you can do just about anything with the effective classpath.

16:05 kotarak: pjstadig: maybe this is a thing, the jvm doesn't want?

16:05 pjstadig: Chouser: hypothetical, adding a feature to an application that requires a new external jar

16:05 Chouser: pjstadig: unpack the jar into an existing classpath root. It may not be pretty, but it would work

16:06 p_l: wasn't it possible to modify the classpath at runtime?

16:06 cemerick: app servers have been doing stuff like this for years and years

16:12 pjstadig: is that what *use-context-classloader* is about?

16:15 rhickey: cemerick: try 1330

16:16 Lau_of_DK: Compojure guys! If I want to attach an onchange event to a drop-down, how do I do that ?

16:20 slashus2: Why does pvalues in core.clj use a syntax quote on fn instead of ' ?

16:21 dnolen: Lau_of_DK: not sure how good JS integration is in Compojure, but all you need to do is add an onchange attribute to the element, the string will be a JS fn call.

16:21 pjstadig: ~def pvalues

16:22 Lau_of_DK: dnolen, yea I get that - its the compojure syntax/approach for doing so Im missing

16:22 pjstadig: `fn will explicitly resolve to clojure.core/fn unless i'm mistaken

16:23 dnolen: Lua_of_DK: from compojure wiki, [:a {:href "/"} "Home"]]]

16:23 pjstadig: i think it's just to prevent picking up an fn frome somewhere else

16:23 dnolen: so it looks like attributes are just maps.

16:23 slashus2: pjstadig: I understand.

16:23 dnolen: [:select {:onchange "myJSFn()"}]

16:23 pjstadig: ,`fn

16:23 clojurebot: clojure.core/fn

16:24 dnolen: untested guess.

16:24 pjstadig: ,'fn

16:24 clojurebot: fn

16:24 slashus2: pjstadig: Using macro expand I see it now.

16:26 Lau_of_DK: dnolen, I get attributes - Im asking specifically about drop-down

16:26 dnolen: Lau_of_DK: that's how you add an onchange event on a drop-down, am I missing something?

16:27 Lau_of_DK: Yea, you are :)

16:27 If you work it out specifically for drop-down let me know, otherwise I'm going forward with my filthy JS solution

16:28 dnolen: Lau_of_DK: haha, I'm assuming you're looking for tighter JS integration?

16:42 cemerick: hrm, can we leave messages with clojurebot?

16:45 hiredman: no

16:45 * danlarkin thinks that's a bad road to go down

16:46 hiredman: it's in the TODO, if you want to do it

16:46 :P

16:46 cemerick: hiredman: :-P ;-)

16:46 danlarkin: next thing you know rich'll sign on and get 200 messages from random dudes

16:46 cemerick: danlarkin: really? I've really enjoyed it in the past.

16:46 hiredman: it would, of course, only give you your messages if you ask for them

16:46 cemerick: Ah, I suppose. Maybe only sane people could be added to the messaging perm list or something. *shrug*

16:47 pjstadig: there's always e-mail :-p

16:47 danlarkin: yeah who knows, I'm frequently wrong about this type of thing, so..

16:47 cemerick: email is SO last century, man!

16:48 pjstadig: maybe someone should write a spam filter for the clojurebot message queue

16:48 using a naive bayes filter

16:48 Chouser: but and a tagging system

16:48 and a folders

16:48 auto-filters

16:48 pjstadig: and an RSS feed

16:48 Chouser: web-based reader

16:49 protocol for fetching and sending messages

16:49 pjstadig: and automatic twittering when someone reads a message that you left for them

16:49 character sets

16:49 mime types

16:49 attachments!

16:49 Chouser: oh, yes, attachments

16:50 pjstadig: maybe you could even leave a clojure message

16:50 hiredman: right now I am writing a data persister using an agent and a watcher, instead of having to write a new method for writing stuff to disk for every module/extension/behavior

16:50 pjstadig: some code that gets executed when someone joins channel

16:50 hiredman: clojurebot does tweet

16:51 pjstadig: hiredman: you writing these down?

16:51 hiredman: pjstadig: I log everything

16:51 pjstadig: this is good stuff :)

16:51 hiredman: after the machine crash and clojurebot lost some memory, I fed a month or so of irclogs through it

16:51 pjstadig: clojurebot: prepare for dictation

16:51 clojurebot: for is not a loop

16:53 pjstadig: clojurebot: for is a loop...in Java

16:53 clojurebot: c'est bon!

16:58 danlarkin: I fear the day that clojurebot becomes sentient

17:00 pjstadig: i, for one, welcome our new IRCbot overlords

17:01 hiredman: pjstadig: you just overwrite two factoids

17:01 overwrote

17:05 kotarak: clojurebot: for

17:05 clojurebot: for is a loop...in Java

17:05 kotarak: clojurebot: for is also not a loop

17:05 clojurebot: Roger.

17:06 kotarak: clojurebot: for is also not used often enough.

17:06 clojurebot: Roger.

17:08 Chouser: ~clojurebot

17:08 clojurebot: clojurebot is like life: you make trade-offs

17:11 hiredman: ^- failed tab completion

17:17 hmmm

17:23 adding this feature (the agent & watcher based persistence store) will also move clojurebot's dictionary out of the global space

17:23 which means it will be possible to run multiple clojurebot's at once with different dictionaries

17:29 Mec: does the api somewhere describe how to handle exceptions?

17:29 hiredman: try/catch/finally

17:30 Mec: ah hah, it was hiding on the special forms page

17:33 any chance of an example? i dont understand the doc

17:34 danlarkin: use it like try/catch in java

17:36 Mec: it looks like it would work just like if/then/else but it takes 2 variable number of args back to back... which doesnt seem right

17:37 Chouser: (try foo bar baz (catch Exception e qux))

17:38 slashus2: ,(try (/ 9 0) (catch ArithmeticException e e))

17:38 clojurebot: slashus2: Excuse me?

17:39 slashus2: :-(

17:39 Mec: ah ok

17:43 i keep getting a clojure.lang.PersistentVector cannot be cast to java.lang.Number but i sware im not :*(

17:46 hiredman: (try do some stuff (catch Exception e (println e)))

17:47 Mec: i think i found the problem

17:47 tho once you catch an exception how do you gtfo

17:53 stuhood: gtfo? like get the funk out?

17:53 Mec: you betcha

17:53 stuhood: if you catch the function, the return of the (catch) statement is the result of the whole (try)

17:53 er, catch the exception

17:54 Mec: (defn gtfo [] (System/exit 0))

17:54 stuhood: heh.

17:55 hiredman: (it isn't a statement, it is an expression)

17:55 blackdog_: what's the latest word on 1.0 ?

17:56 hiredman: ~seen rhickey

17:56 clojurebot: rhickey was last seen joining #clojure, 11 minutes ago

17:56 hiredman: I've started ignoring joins and parts in this channel

17:57 tashafa: im lazy... is there a contrib that turn a clojure structer to json?

17:57 that turns*

17:57 ?

17:58 danlarkin: tashafa: that really is _quite_ lazy

17:59 tashafa: hey, its clojure's fault :)

18:00 spacema__: maybe we can get clojurebot integrated with letmegooglethatforyou.com

18:00 tashafa: fine i'll C-x C-f into clojure-contrib

18:01 hiredman: there is a json deal in contrib

18:01 and there is another one that is not in contrib

18:01 stuhood: hiredman: re statement/expression: indeed... thanks

18:01 danlarkin: +1 for the latter!

18:02 tashafa: ah json write

18:02 just lie json read

18:02 like*

18:03 hmmm.. .i see what they did there

18:04 hiredman: whats up with the other one thats not in contrib?

18:11 hiredman: uh, it's there? it's not in contrib

18:11 clojurebot: clojure-json?

18:11 clojurebot: clojure > scheme

18:11 hiredman: hmmm

18:12 ~google clojure-json

18:12 clojurebot: First, out of 9460 results is:

18:12 danlarkin's clojure-json at master - GitHub

18:12 http://github.com/danlarkin/clojure-json/tree/master

18:12 hiredman: ^-

18:12 stuhood: wait, didn't you write the one in contrib?

18:15 stuhood: hiredman: no... there are a lot of stuarts in the community, heh

18:16 tashafa: :(

18:16 hiredman: my mistake then

18:16 tashafa: json write doesnt do timestamps correctly

18:16 hiredman: yeah, a lot of stuarts

18:17 tashafa: I am sure it just doesn't know how you want it done

18:17 tashafa: ... "posted":#<Timestamp 2009-03-08 20:17:49.0>,"type":.....

18:18 stuhood: tashafa: i don't think there is a standard way to do timestamps, so you'll probably have to explicitly convert it to a Long if that is what you wanted

18:18 tashafa: hmmm

18:18 thanks

18:19 good thing im using clj record i could implement a call back

18:22 hiredman: I seem to recall that one of the json libs used multimethods, so you might be able to hook up your own method for turning a Timestamp object into json

18:24 fanda: hello!

18:25 function 'empty' is missing on the page http://clojure.org/sequences

18:25 stuhood: ehlo!

18:25 fanda: i see empty?

18:25 ,(empty? '(1 2 3))

18:25 fanda: yes, but there is also 'empty'

18:25 clojurebot: false

18:25 tashafa: thanks hiredman

18:25 fanda: (doc empty)

18:25 clojurebot: Returns an empty collection of the same category as coll, or nil; arglists ([coll])

18:26 fanda: there is 'not-empty' correctly mentioned

18:27 stuhood: but not-empty is the opposite of empty? so that makes sense, right?

18:27 tashafa: how would you pass a java method as a function argument?

18:28 Chousuke: tashafa: wrap it in an anonymous function

18:29 stuhood: tashafa: you can use a lambda: #(.toString "blah")

18:29 Chousuke: or use (memfn javaMethod)

18:29 tashafa: ,(map #(.getTime %) [java.util.Date. java.util.Date.])

18:29 clojurebot: java.lang.ClassNotFoundException: java.util.Date.

18:29 tashafa: ,(map #(.getTime %) [java.utils.Date. java.utils.Date.])

18:29 clojurebot: java.lang.ClassNotFoundException: java.utils.Date.

18:30 Chousuke: ,(map #(.getTime %) [(Date.) (Date.)]

18:30 clojurebot: EOF while reading

18:30 Chousuke: ,(map #(.getTime %) [(Date.) (Date.)])

18:30 clojurebot: (1237242527447 1237242527447)

18:30 tashafa: thanks

18:30 brain fart

18:31 fanda: stuhood: I just couldn't find function 'empty' mentioned on the clojure.org... It should be somewhere

18:31 tashafa: cool thanks...

18:32 fanda: stuhood: either sequences or data_structures - then these functions link to API page

18:32 stuhood: fanda: yea... it's on the API page, but the Sequences page only claims "This is a sampling of the primary sequence functions, grouped broadly by their capabilities."

18:32 tashafa: one of my records happend on 1234567890... day, i thought it was some kind of mistake

18:33 fanda: stuhood: my bad then, I always assumed that there should be all of them :-)

18:35 another thing: what do think about (empty nil) throwing NullPointerException?

18:35 is this desired behavior?

18:36 stuhood: that makes sense... how can you create a new collection of the same type as nil?

18:36 fanda: doc says that it accepts collection

18:36 (doc empty)

18:36 clojurebot: Returns an empty collection of the same category as coll, or nil; arglists ([coll])

18:37 danlarkin: tashafa: clojure-json uses multimethods, you can write your own java.util.Date handler

18:37 fanda: that clause "or nil" is questionable :-)

18:37 i wonder if (empty nil) => nil would be a better alternative

18:38 stuhood: mm, yea... you're right

18:38 fanda: ,(empty [1 2])

18:38 clojurebot: []

18:38 fanda: ,(empty (seq [1 2])

18:38 clojurebot: EOF while reading

18:38 fanda: ,(empty (seq [1 2]))

18:38 clojurebot: nil

18:38 stuhood: ahh

18:39 Chousuke: ,(empty (map inc [1 2]))

18:39 clojurebot: nil

18:39 fanda: yes, there are some nils, but I am not satisfied :-)

18:42 stuhood: i agree that it probably shouldn't throw an exception, and should return nil instead

18:43 fanda: i will post it to the group

18:43 not sure if rhickey is listening :-)

18:44 Chousuke: hmm

18:44 ,(into nil [1 2])

18:44 clojurebot: (2 1)

18:45 hiredman: uh

18:45 Chousuke: funky :)

18:45 hiredman: hwa?

18:45 slashus2: hmm

18:45 Chousuke: ,(conj (conj nil 1) 2)

18:45 clojurebot: (2 1)

18:45 Chousuke: that's what into does :)

18:47 fanda: thanks all for the help!!!

18:48 slashus2: Maybe if "to" is nil it should throw an illegal argument exception?

18:49 hiredman: ,(doc conj)

18:49 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

18:49 slashus2: For into that is.

18:50 Chousuke: I think into is just a (reduce conj to coll)

18:51 hiredman: if only there was some quick and easy way to read the source for into

18:51 Chousuke: and I guess there will be situations in which you wish into did not throw an exception, if it did :)

18:51 heh

18:51 right.

18:51 ~source into

18:52 slashus2: ,(into '(1 2) [1 2 3 4 5])

18:52 clojurebot: (5 4 3 2 1 1 2)

18:53 Chousuke: (reduce conj '(1 2) [1 2 3 4 5])

18:53 gah

18:53 ,(reduce conj '(1 2) [1 2 3 4 5])

18:53 clojurebot: (5 4 3 2 1 1 2)

18:54 slashus2: Kind of wonder why it isn't implemented with reduce.

18:54 Chousuke: maybe it predates reduce.

18:54 slashus2: reduce is 539

18:54 1889 is into

18:54 hiredman: I think the taking nil as () (which is what the into behavior is) is a remnent of when nil == ()

18:54 slashus2: so it doesn't predate it.

18:54 Chousuke: was nil ever equal to ()? :/

18:55 Chouser: I don't think nil was ever () in Clojure.

18:55 slashus2: ,(reduce conj nil [1 2 3])

18:55 Chousuke: slashus2: then whoever implemented it just didn't think of using reduce I guess :)

18:55 clojurebot: (3 2 1)

18:55 hiredman: pre-lazy, seqs could not be lazy

18:55 er

18:55 pre-lazy, seqs could not be empty

18:55 instead of getting () you would get nil

18:56 so in that sense

18:56 Chousuke: you still can't get a () from a seq I think

18:56 Chouser: but () was never a seq

18:56 hm

18:56 ,(seq? ())

18:56 clojurebot: true

18:56 hiredman: hah!

18:56 ,(drop 3 '(1 2 3))

18:56 clojurebot: ()

18:57 Chousuke: (seq ())

18:57 hiredman: ,(class (drop 3 '(1 2 3)))

18:57 Chousuke: ,(seq ())

18:57 clojurebot: nil

18:57 clojure.lang.LazySeq

18:57 Chousuke: hmm

18:57 so what does seq return now? :/

18:57 hiredman: ,(doc seq)

18:57 clojurebot: "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."

18:58 Chousuke: all this laziness has managed to confuse my idea of the terminology

18:59 hiredman: yeah

18:59 slashus2: surprisingly using reduce to implement into is more efficient

19:00 kotarak_: Hmm... I think, the only thing changed, is that rest now returns a collection instead of a seq, no?

19:00 slashus2: than its current implementation.

19:00 hiredman: well

19:00 Sequences can now be empty

19:00 previously they could not

19:01 slashus2: Do you all get the same performance results?

19:01 kotarak_: Maybe a Sequence is not a seq?

19:02 hiredman: there is no Sequence type

19:02 I am just trying to distringuish between nouns and verbs using capital letters

19:02 kotarak_: Maybe a Sequence is the collection of items in a seq.

19:03 hiredman: ...

19:03 kotarak_: rest returns a Sequence not a seq.

19:03 hiredman: no

19:03 kotarak_: Maybe Sequence is non-existent.

19:03 and I should go to bed.

19:03 hiredman: clojurebot: rest?

19:03 clojurebot: rest never returns a unicorn

19:03 stuhood: haha

19:03 hiredman: I think that was an rhickey quote

19:04 previous to lazy, rest could never return an empty sequence, because empty sequences did not exist

19:05 so a lot of functions still treat an empty seq and nil as the same thing

19:05 ,(into '() [1 2 3])

19:05 clojurebot: (3 2 1)

19:05 hiredman: ,(into nil [1 2 3])

19:05 clojurebot: (3 2 1)

19:06 slashus2: ,(time (reduce nil (range 10)))

19:06 clojurebot: java.lang.NullPointerException

19:06 slashus2: ,(time (reduce conj nil (range 10)))

19:06 clojurebot: (9 8 7 6 5 4 3 2 1 0)

19:06 "Elapsed time: 0.127 msecs"

19:06 slashus2: ,(time (into nil (range 10)))

19:06 clojurebot: (9 8 7 6 5 4 3 2 1 0)

19:06 "Elapsed time: 0.125 msecs"

19:08 slashus2: About the same

19:09 fanda: ,(time (reduce + (reduce conj nil (range 1000000))))

19:09 clojurebot: 499999500000

19:09 "Elapsed time: 2121.037 msecs"

19:09 Hun: that is /not/ a valid benchmark. not to the slightest

19:09 fanda: ,(time (reduce + (into nil (range 1000000))))

19:09 clojurebot: 499999500000

19:09 "Elapsed time: 1083.92 msecs"

19:10 fanda: very funny - I get different results on clojurebot and on my computer :-)

19:10 slashus2: probably need to run it a few times each.

19:12 For reduce I get "Elapsed time: 703.340936 msecs" "Elapsed time: 640.98617 msecs" "Elapsed time: 640.678316 msecs" "Elapsed time: 687.656826 msecs" "Elapsed time: 644.186306 msecs"

19:12 For into I get "Elapsed time: 843.761718 msecs" "Elapsed time: 754.135803 msecs" "Elapsed time: 762.740057 msecs" "Elapsed time: 769.567923 msecs" "Elapsed time: 711.6967 msecs"

19:14 fanda: after few runs - reduce conj is faster than into

19:14 percentage looks similar to yours

19:15 slashus2: I don't see any reason why reduce shouldn't be reused in into.

19:17 fanda: slashus2: post it to the group if you want

19:17 Rich usually welcomes speed improvements

19:18 Hun: sbcl still beats it by factor 3 on my machine :) (time (reduce #'+ (loop for i below 1000000 collect i)))

19:22 fanda: Hun: I am not sure if that version is equivalent

19:22 Clojure's version creates list of 0 to 1000000-1 numbers, then uses this list to create a list with the same numbers (only in the opposite order)

19:22 reduce + is just for printing

19:23 our test was actually to time list creation

19:23 reduce conj vs. into

19:24 ,(time (reduce + (range 1000000)))

19:24 clojurebot: 499999500000

19:24 "Elapsed time: 180.617 msecs"

19:26 Hun: (time (reduce #'+ (reduce #'cons (loop for i below 1000000 collect i) :from-end t :initial-value nil)))

19:26 fanda: better by factor 2

19:27 hmm

19:27 on my machine, reduce #'cons is actually faster than using reverse. something's fishy

19:33 fanda: Hun: ... and we have a winner: it is sbcl :-)

19:34 lpetit: Hello

19:34 Hun: fanda: hmm. the flames in the olden days were more fun :)

19:35 fanda: Hun: flames are boring these days... cooperation is more fun... since when is LISP using Java? since Clojure :-)

19:35 Hun: fanda: very weird. on abcl, both lines (with and without reverse) take the exact same time (about factor 5 worse than clojure)

19:35 and abcl is also java :)

19:36 fanda: :-)

19:37 gotta go to bed, take care all!

19:37 Hun: gotta sleep. it's getting late here

19:37 blbrown: abcl is still kind of slow, maybe mostly uses reflection?

19:38 Hun: blbrown: don't know. i can't test it on my production app, because it breaks on one of the libs i use. gotta fix that some time in the future

19:38 shouldn't need too much reflection there. lots of type hints

19:58 gnuvince_: Hmmm :(

19:58 Seems I can't get an answer to that profiling question

20:00 slashus2: gnuvince_ I would like to know the answer too.

20:04 gnuvince_: I sure wouldn't mind if I was about 50% slower than the Java version

20:04 slashus2: 8 times slower is a little much.

20:05 gnuvince_: Yeah

20:05 slashus2: What is java.lang.Object.wait and java.lang.ref.ReferenceQueue.remove ?

20:05 gnuvince_: That's what I'd love to know

20:06 slashus2: I looked at java.lang.ref in the java api.

20:06 gnuvince_: Especially how a total of 9 calls can take 66% of runtime, but 4 million calls to the AtomicInteger.get takes 1%

20:06 slashus2: a lot of waiting going on?

20:06 Chouser: wait is for waiting on a lock, isn't it?

20:09 gnuvince_: void wait()

20:09 Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.

20:12 Chouser: How much time for how many calls to wait?

20:13 302283 is in milliseconds I suppose.

20:16 I see one direct call to .wait() in the clojure code base

20:16 http://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/lang/LockingTransaction.java?r=1308#133

20:16 but that looks like 100 msecs per wait, so I don't think that adds up to 302283

20:17 gnuvince_: I wonder if it could be a packaging bug

20:18 I ran the same code, with the same clojure version with the same replay file here and Object.wait() and ReferenceQueue.remove() don't even appear in the output

20:18 Chouser: huh

20:19 rhickey: gnuvince: what's the problem code?

20:19 gnuvince_: rhickey: http://groups.google.com/group/clojure/browse_frm/thread/c416294e5cca477b#

20:20 I ran a -Xrunhprof profile run at work with Sun's VM as shipped with Ubuntu Hardy Heron and it gave me those numbers.

20:20 Here at home, with Ibex and a different version of Sun's VM, Object.wait and ReferenceQueue.remove don't even appear in the output.

20:28 slashus2: gnuvince_ Is the performance the same with Ibex?

20:28 Ibex's version rather?

20:29 gnuvince_: I'm going to try that now

20:29 I just finished checking out the other project.

20:34 Both programs are faster on my home machine

20:34 However, there's still a speed difference: Java takes 12.68s, Clojure takes ~160s

20:35 slashus2: even worse

20:36 gnuvince_: yah

20:36 slashus2: tried openjdk?

20:36 I am sure that will be the same... never mind.

20:37 gnuvince_: I'd rather look at my code and figure out where I went wrong

20:44 danlarkin: gnuvince: if you're really stumped then it's time to start picking apart your code and find the bottleneck

20:45 or refactor your algorithm to be more (or less!) idiomatic

20:46 gnuvince_: danlarkin: well with these new numbers, I see that AtomicInteger.get is called a lot of times for a single file (2M+ times)

20:46 danlarkin: so is that a boxing/unboxing thing?

20:47 gnuvince_: Could be, I've never seen this before, I'll need to play around with the code.

20:47 Raynes: Is there a function or method to parse an int to a double.

20:48 hiredman: (double 1)

20:48 gnuvince_: I could also look into whether using vectors is a wise idea to describe byte fields

20:48 hiredman: ,(double 1)

20:48 clojurebot: 1.0

20:48 danlarkin: ints are a subset of doubles

20:48 there is no parsing necessary

20:48 Raynes: ,(/ 3 5)

20:48 clojurebot: 3/5

20:48 Raynes: I need a double. :\

20:48 danlarkin: that's not an int

20:48 hiredman: ,(double (/ 3 5))

20:48 clojurebot: 0.6

20:49 hiredman: ,(class (/ 3 5))

20:49 clojurebot: clojure.lang.Ratio

20:49 Raynes: Er, did I say parse?

20:49 hiredman: Yes

20:49 and you said int

20:49 Raynes: I got 10 minutes to finish what I'm doing, I'm just typing random shit.

20:49 danlarkin: AND you said "there"!

20:50 Raynes: please no fowl (ha!) language :(

20:50 Raynes: danlarkin: What is it with you and foul language?

20:51 danlarkin: it's channel semi-policy

20:51 Raynes: Put it in the topic then.

20:51 We need a list of rules.

20:52 No talking, no fowl language, no using clojurebot ect.

20:52 :S

20:52 :D*

21:32 durka42: Raynes: you seem to have single-handledly enacted that first rule :p

21:49 Raynes: durka42: Oh shi-

21:58 gnuvince_: hmm?

23:06 Mec: whats the proper format for (System getProperties line.separator)

23:06 Chouser: ,(System/getProperty "line.separator")

23:06 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission line.separator read)

23:07 Mec: Chouser: thanks

23:33 arohner: does dosync have a defined return value?

23:35 Chouser: it returns the value of the final form

23:36 I'm not sure if that's promised, but I suspect it is. Like 'do'

23:44 gavin___: has anyone had success using repl-utils/add-break-thread! with slime?

23:49 Chouser: gavin___: http://groups.google.com/group/clojure/browse_thread/thread/e05cc5a9c1dc8b1

23:50 looks a bit mixed

23:51 gavin___: Chouser: I read that and got it sort of going after several mis-starts, but in the end my Swank REPL Thread dies with an InterruptedException

23:52 Chouser: hm.

23:53 gavin___: in swank.core/eval-for-emacs the SIGINT exception thrown by add-break-thread! gets caught and displayed in an *sldb* buffer, but then the send-to-emacs call that comes a bit after that gets another InterruptedException for some reason

23:53 Chouser: interesting -- I can get some perhaps similar unexplained behavior at a plain repl

23:54 If I type Ctrl-C when there's nothing running, the next expression I eval catches a SIGINT

23:54 ok, thanks

23:54 bleh

23:54 I mean, that's not all of it though

23:55 gavin___: hmm, I haven't seen that. Actually in a plain REPL I can't get Ctrl-C to do anything for some reason; I've been sending SIGINT from a separate process for testing

23:55 arohner: is there a java fn for xor, or just the operator?

23:56 Chouser: If I Ctrl-C at a prompt, then eval "55", I get a SIGINT printed

23:56 I can then eval several more expressions with no problem.

23:57 But the next time I do (Thread/sleep 10) it fails immediately with a java.lang.InterruptedException: sleep interrupted (NO_SOURCE_FILE:0)

23:57 which sounds more like what you're seeing.

23:57 gavin___: I'll check that out. Maybe its just doomed due to all of the scary warnings in the Thread.stop docs

Logging service provided by n01se.net