#clojure log - May 29 2009

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

0:29 djpowell: hoeck: yeah that is easier

0:30 I'm trying to wrap log4j calls in clojure, so I need to pass the name of the wrapper class to log4j so that it can figure out the line number of the caller from the stack trace

0:31 I'm seeing that my function proxies the call to the clojure logging function via RestFn.invoke. What is RestFn?

0:37 opqdonut: how do I read a string into an int?

0:40 djpowell: ,(Integer/parseInt "123")

0:40 clojurebot: 123

0:41 djpowell: is there a better way that isn't restricted to Java ints?

0:42 hmm, this is better:

0:42 ,(read-string "123")

0:42 clojurebot: 123

0:42 talios: ,(Integer/valueOf "5")

0:42 clojurebot: 5

0:47 djpowell: ,(num (read-string "1234")) ; if you want to fail if it isn't a num, but still support the whole numeric tower

0:47 clojurebot: 1234

3:20 alinp: hi

3:20 Chouser: hi

3:20 alinp: can anyone please tell me what is wrong with this code: http://pastie.org/493850

3:20 ?

3:20 I get NPE ... and I don't really get it

3:23 I don't really get it ... means that I don't got an idea where it comes from

3:23 Chousuke: alinp: the nil is the initial value of the agent, and you're trying to add 1 to it.

3:24 or maybe not... hm

3:24 alinp: yey

3:24 thanks Chousuke

3:24 this was it ...

3:24 at least for me

3:24 but .. shouldn't be the case

3:25 Chousuke: (doc send)

3:25 clojurebot: "([a f & args]); Dispatch an action to an agent. Returns the agent immediately. Subsequently, in a thread from a thread pool, the state of the agent will be set to the value of: (apply action-fn state-of-agent args)"

3:25 alinp: because I'm not adding to agent value

3:26 jdz: you are

3:26 Chousuke: the agent's state goes in as the first parameter to f

3:26 alinp: (defn second-test [coll]

3:26 (map (fn [x] (send (agent nil) (fn [_] (+ x 1)))) coll))

3:26 (def x (second-test (list 1 2 3)))

3:26 and it works

3:27 also the agent is having nil value

3:27 Chousuke: yeah, because now you're ignoring the agent's value :)

3:27 instead, you're using x

3:27 alinp: oh, crap

3:27 jdz: why are you creating agents with nil state?

3:27 alinp: the agent's value is going instead of _

3:27 Chousuke: alinp: ?

3:27 alinp: don't know, because I don't have an initial state of it ?!

3:28 Chousuke: alinp: _ is just an "I don't care" marker

3:28 alinp: yes, this is what I said .. .

3:28 Chousuke: it still gets assigned the value though. which is the agent's state in this case.

3:28 alinp: I didn't saw where the agent's value was placed

3:28 Chousuke: it's not easy to see from that, I agree :/

3:29 in your test-map call it kinda looks like y would be the list values, but they're not.

3:29 instead, you're completely ignoring the list :)

3:30 alinp: I see

3:30 thanks

3:30 so .. there is a solution for that ?

3:30 or the solution will be not to use nil ?

3:30 Chousuke: is there a problem to solve? what do you actually want to do?

3:31 have an agent and add a listful of value to it?

3:31 values*

3:31 alinp: no, have a list and apply a function to all elements that is spawning a thread for each element

3:31 Chousuke: ah

3:32 alinp: and I don't want to do it (thread spawning) outside of this function

3:32 I just want the function to get the same params as map function, but, backstage to apply function to each element in a separate thread

3:32 Chousuke: maybe you should use futures.

3:33 alinp: well, but can't be done this way ? :)

3:33 Chousuke: hmm

3:33 alinp: to be honest, I'm just playing

3:33 Chousuke: sure it can, but... gmm

3:33 alinp: it's not something for production or so ..

3:33 Chousuke: but if you want to use agents: (map (fn [item] (send-off (agent initvalue) f item)) coll)

3:34 rhickey: ,(doc pmap)

3:34 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."

3:34 Chousuke: or that :D

3:35 alinp: ha

3:35 yes, is what I want to do :)

3:35 ok, thank you

3:35 I'll see about that

3:36 Chouser: alinp: and then you can look at the definition of pmap and learn how its done. :-)

3:36 alinp: yes, sure, this is what I have in mind :D

3:36 *I had

3:43 Chousuke:

3:43 ,(map (fn [x] (send (agent nil) (fn [_] (+ x 1)))) coll))

3:43 clojurebot: java.lang.Exception: Unable to resolve symbol: coll in this context

3:44 alinp: ,(map (fn [x] (send (agent nil) (fn [_] (+ x 1)))) (list 1 2 3)))

3:44 clojurebot: (#<Agent@15ec870: nil> #<Agent@1b95de0: nil> #<Agent@c22530: nil>)

3:44 alinp: hmmmm

3:44 wtf ?

3:45 ,(map (fn [item] (send-off (agent 0) f item)) (list 1 2 3))

3:45 clojurebot: java.lang.Exception: Unable to resolve symbol: f in this context

3:45 alinp: (def f (fn [p] (+ p 1)))

3:45 (map (fn [item] (send-off (agent 0) f item)) (list 1 2 3))

3:45 java.lang.IllegalArgumentException: Wrong number of args passed to: user$f

3:46 (map (fn [item] (send-off (agent 0) (f item))) (list 1 2 3))

3:46 java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

3:47 (map (fn [item] (send-off (agent 0) (fn [_] (f item)))) (list 1 2 3))

3:47 it seems that I need to do something like this

3:49 hoeck: alinp: your function f has to take the agent state as the first arg

3:50 alinp: it should be (defn f [p item] (+ p item))

3:50 Chousuke: yes

3:50 functions sent to agents must always take the agent as the first parameter

3:50 the state of the agent that is

3:50 alinp: oh, I see

3:50 Chousuke: just send + to it :)

3:51 ,(map #(send-off (agent 5) + %) [1 2 3])

3:51 clojurebot: (#<Agent@7704dd: 6> #<Agent@1e05ef2: 5> #<Agent@1799932: 5>)

3:52 Chousuke: hmm

3:52 that's not what I expected :D

3:52 alinp: ha

3:52 :)

3:52 Chousuke: might be the asynchrony

3:52 the rest of the agents didn't complete the action before the map thing printed them

3:53 ,(map #(send (agent 5) + %) [1 2 3])

3:53 clojurebot: (#<Agent@8eb8bf: 5> #<Agent@31f94: 5> #<Agent@10e58a3: 5>)

3:53 Chousuke: hmm.

3:53 alinp: (defn my-map [f coll]

3:53 (map

3:53 (fn [item] (send-off (agent nil) (fn [_] (f item))))

3:53 coll)

3:53 )

3:53 this is what I made ...

3:53 and it seems it working ;)

3:54 Chousuke: yeah, that would work.

3:54 and send and send-off are both asynchronous

3:54 :p

3:54 alinp: yep

3:54 Chousuke: also, putting the closing paren on its own line is not very lispy :)

3:54 alinp: the thing is that I was taking always the value of agent

3:55 Chousuke: you should learn the Real Way!

3:55 alinp: and not the value of each item

3:55 Chousuke: you'll ~never see code like that anyway.

3:55 alinp: you're talking about what piece of code ? (mine, of course, but which)

3:55 Chousuke: so you need to get used to the closing parens not being on separated

3:55 the ) at the end

3:55 it should be after coll)

3:56 and also the end paren for defn should be after those

3:56 lisppaste8: url

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

3:56 alinp: I see, well .. I saw plenty of clojure code this way ...

3:56 Chousuke: where? :/

3:57 alinp: I don't remember right now ... but I'll be sure to show you some when I see it ;)

3:58 "and also the end paren for defn should be after those"

3:58 what do you mean ?

3:58 (defn my-map [f coll]

3:58 (map

3:58 (fn [item] (send-off (agent nil) (fn [_] (f item))))

3:58 coll))

3:58 this is what you mean ?

3:59 lisppaste8: chousuke pasted "coding style" at http://paste.lisp.org/display/81021

4:00 alinp: yep, cool, thanks

4:00 Chousuke: when writing lisp, don't match parentheses manually; let the editor do it for you

4:00 alinp: well, yes... but

4:00 anyway, is better than haskell

4:01 I hate the indentation stuff

4:01 tabs over spaces ... etc

4:01 Chousuke: lisp has no forced indentation but there are of course conventions you should follow.

4:02 for example, one indent is generally two spaces

4:02 alinp: yes, this is how my vim is configured for clj

4:05 Chousuke: grouping the end parens has the effect that lisp code usually has quite a distinct "shape"

4:05 and if that shape looks weird, you may need a rewrite ;)

4:53 durka42: github's clojure highlighter has a few bugs >:o

4:55 hiredman: so does the php highlighter

4:58 gnuvince: I blame Ruby

5:15 alinp: it is possible in clojure to create an initial list with n agents ?

5:15 or .. n elements

5:15 it doesn't matter if are agents or other type

5:16 cmvkk: like this?

5:16 ,(repeat 5 0)

5:16 clojurebot: (0 0 0 0 0)

5:16 alinp: make-array is used for classes

5:16 yes, like this :)

5:16 thanks cmvkk

5:17 {newbie}: Hi I have a list of stuff I want to pass to a var arg function?

5:17 how do i destruct the list into multiple values?

5:17 Chouser: {newbie}: apply

5:18 alinp: {newbie}: map

5:18 {newbie}: thanks ^^

5:18 alinp: hmmm, apply will be better, Chouser is right

6:00 hiredman: ,(map agent (repeate 5 nil))

6:00 clojurebot: java.lang.Exception: Unable to resolve symbol: repeate in this context

6:00 hiredman: ,(map agent (repeat 5 nil))

6:00 clojurebot: (#<Agent@866463: nil> #<Agent@128b564: nil> #<Agent@19ce804: nil> #<Agent@446cc5: nil> #<Agent@4127cf: nil>)

6:25 hiredman: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated

6:25 Nice

6:47 rhickey: ooh: http://java.sun.com/javase/6/webnotes/6u14.html

6:47 The -XX:+DoEscapeAnalysis option directs HotSpot to look for objects that are created and referenced by a single thread within the scope of a method compilation. Allocation is omitted for such non-escaping objects, and their fields are treated as local variables, often residing in machine registers. Synchronization on non-escaping objects is also elided.

6:48 Chousuke: cool

6:49 stuartsierra: So that eliminates the object-allocation penalty?

6:50 Chousuke: I wish I weren't on OS X so I could try and see what kind of effect that has :)

6:50 rhickey: Chousuke: me too :(

6:50 stuartsierra: in some cases - it will be interesting to see which ones

6:58 durka42: i like -XX:+UnlockExperimentalVMOptions

6:58 clojure has *leveled up*! clojure has unlocked new VM features!

6:59 Chousuke: heh

6:59 hmm, there's a recent java developer preview update on ADC

6:59 let's see which version it is ;P

7:00 damn, 1.6.0_13

7:00 no fair

7:01 still, probably worth upgrading

7:02 rhickey: how's everyone doing with chunked seqs?

7:03 Chouser: haven't noticed any problems

7:04 could lazilypersistentvectors and arraymaps each provide one big chunk?

7:06 rhickey: Chouser: that would actually be bad. The beauty of chunks is that they are just a slightly expanded version of seqs - not realizing full intermediate results is a big win

7:07 Chouser: does a chunk stay the same size through the whole chain?

7:07 I hadn't thought about that, but I guess it must.

7:07 rhickey: not necesarily

7:08 you can have heterogeneous seqs, with some chunks some not

7:08 Chouser: but most intermediate funcs (map, filter, etc.) won't do extra work to break up or coalesce chunks?

7:09 rhickey: Chouser: no, ideally they should copy the incoming chunk size, filter and its ilk being the exception

7:10 chunked-seq, or whatever we call it, will actually drop the chunk if it is empty - (chunked-seq [] foo) => foo

7:11 sorry, meant chunked-cons above

7:11 (chunked-cons [] foo) => foo

7:12 Chouser: ah, now I see, by through the chain you mean chain of calls, not chain of seqs

7:12 clojurebot: Who??

7:13 Chouser: yes, sorry, the call chain

7:13 rhickey: then yes, will be same size, thus whole-coll-as-chunk = bad

7:13 Chouser: got it

7:14 rhickey: that's why LazilyPersistentVector.ChunkedSeq is the way it is

7:14 Chouser: so... lpv and arraymap could provide artificially small chunks of themselves at whatever the "ideal" size is.

7:14 oh.

7:14 * Chouser looks at the code

7:14 Chouser: 32. ok.

7:15 that was my next question

7:15 rhickey: there is still an issue for multi-seq map regarding chunk alignment

7:16 ditto any other multi-seq consumer, like zipmap or interleave

7:16 Chouser: mmm, sure.

7:16 rhickey: the simplest default is to do chunks only when aligned

7:16 thus 32

7:17 but not guaranteed, since e.g. hashmap chunks are sparse

7:17 Chouser: any sense of how small chunks can be and still be worth the overhead (if any)? 2 items? 4?

7:18 rhickey: Chouser: since the chunked seqs are as fast as the original seqs when used as ordinary seqs, I think it is all win, but haven't tried very small chunks

7:18 Chouser: I'm just thinking that the second-simplest behavior for multi-seq would be to produce one (small) chunk for each range of fully-overlapping chunks.

7:19 rhickey: Chouser: the trick is remembering the half-chunk you didn't yet consume

7:19 Chouser: yeah. all them. :-)

7:19 rhickey: I thought about it and got a headache

7:22 but, one of the reasons this is in trunk is I welcome contributions towards getting it fully done. I foresee the need for:

7:22 chunked arrayseqs

7:22 chunked hashmap seqs, plus chunked keys and vals seqs

7:22 multi-arg map

7:22 vectors of primitives

7:23 chunked versions of arithmetic ops, both chunk/chunk and chunk/scalar

7:23 chunked-map which takes a fn expecting chunks

7:23 chunked-pmap

7:24 integration of chunking logic in the core seq fns where it makes sense - I'll do map/filter/reduce as examples

7:24 Chouser: I don't understand chunked arithmetic

7:24 rhickey: (+ chunk-of-ints chunk-of-ints) => chunk-of-ints

7:26 Chouser: can't do that with seqs now, can you?

7:26 rhickey: (chunked-map + int-vector1 int-vector2)

7:26 the perf of this would be as good as loops with primitives

7:28 Chouser: map* as pasted yesterday doesn't tell f it's got a chunk. is there some other api detail I'm missing?

7:28 rhickey: so, people could use vectors of primitives transparently and at a high leve like they do vectors of objects, and get fast math when needed, without going to Java arrays

7:29 Chouser: sounds absolutely gorgeous, but I'm not seeing how all the pieces fit together yet.

7:29 rhickey: Chouser: sorry if this is confusing, the logic in map* of yesterday is going to end up in regular map. After that, there will be a map-chunked which takes a fn that *expects* a chunk, and requires a chunked seq as input

7:30 + would become such a fn

7:30 (map-chunked + int-vec1 int-vec2), would pass the first chunk from each to +

7:31 + would be overloaded for chunks

7:31 so instead of boxing each int, we 'box' entire chunks in int-vectors

7:31 stuartsierra: Just got my "Programming Clojure" -- pretty nifty.

7:31 Chouser: oh, so map-chunked is different from map* and map

7:31 (yes, I understand map* is going away)

7:31 rhickey: Chouser: yes, map-chunked passes chunks o f

7:31 to f

7:32 Chouser: got it.

7:32 and what are these vectors of primitives you slipped in there?

7:33 rhickey: basically exactly like vectors, except specialized for int/long/float/double. They will present the exact interface as vectors, but will ensure that things put in will 'fit' in the primitive types

7:33 (int-vec 1 2 3 4)

7:34 hm, int-vector I guess

7:34 Chouser: sounds like a lot more boilerplate Java code.

7:34 but great to use! :-)

7:34 rhickey: when seq'ed, a primitive vector's chunks will be chunks of primitives

7:35 rsynnott: stuartsierra: oh, they released it?

7:35 * rsynnott still has a beta pdf of some sort

7:35 rhickey: math ops will detect such chunks and do primitive/primitive op, boxing occurring once per chunk

7:36 Chouser: ah, sure. whatever seq produces would still need to be boxed, so without chunks you'd get some memory savings, but no performance boost. boxing whole chunks gives perf as well.

7:36 stuhood: so the main benefit is speed then?

7:37 imo, the speed isn't worth it unless the chunking can be done transparently

7:37 stuartsierra: rsynnott: yes

7:37 Chouser: stuhood: it will be

7:38 stuhood: ah, i misunderstood map-chunked

7:38 asbjxrn: Even non-transparent speed is worth it if you need it.

7:38 Chouser: stuhood: a regular vector of regular objects passed through regular map/filter/reduce should run quite a bit faster with chunks under the hood.

7:39 rhickey: stuhood: it might seem to be only about perf, but there comes a point where perf determines the viability of using the higher-level ops for everything. The model right now when switching to arrays + primitives + loops is very different

7:39 this is best-of-both-worlds, IMO

7:39 Chouser: right, map-chunked is not transparent, but is more pleasant than loop/recur when your only reason for doing so was perf (via primitives)

7:40 rhickey: also the increased granularity means pmap might makes sense in more cases, since the per-step work unit is bigger

7:40 Chouser: ah, nice

12:49 rhickey: but the transparency is key - right now all the vector seqs are chunked, and no one seems to care

12:49 stuhood: could map defer to map-chunked transparently?

12:49 oh, gotcha

12:49 rhickey: stuhood: unlikely

12:50 stuhood: could the sequence just implement another interface that map/reduce/filter would check for?

12:50 Chouser: I do wonder if we have as much usage of svn head as we did.

12:51 I know I'm running 1.0.0 more often then I ever ran old revs before.

12:51 rhickey: stuhood: it does and they will, but that doesn't mean the fn is ready to accept chunks

12:51 stuhood: ahhh, doh.

12:52 * rhickey thinks map-chunked will be called map* in the end

12:52 stuhood: could it not fall back to map if the function didn't have a high enough arity?

12:52 Chouser: better than arity would be metadata explicitly saying it can do chunks

12:52 rhickey: stuhood: it's not a question of arity, both could have arity 1

12:52 Chouser: but you'd want to determine that at compile time, wouldn't you?

12:53 stuhood: rhickey: it is if you (apply) the chunk to the function

12:53 Chousuke: a new kind of type hint? :)

12:53 Chouser: so it'd be more like ... metadata on that specific AFn subclass rather than the closure instance. heh.

12:53 stuhood: oh, nvm.

12:54 scuse me... too much typing, not enough thinking

12:55 rhickey: Chouser: one of the earlier models was chunked seqs were seqs of chunks - it didn't work out, and I'm not sure with metadata it could do the right thing, but maybe

12:55 Mathematica has a similar notion

12:56 listable

12:56 {newbie}: I define a strut but i can acess the struct members inside a function. An exception is thrown "Unable to resolve classname")

12:56 rhickey: http://reference.wolfram.com/mathematica/ref/Listable.html

12:56 {newbie}: can't*

13:02 it works outside a functioin

13:02 function*

13:03 Chousuke: you need to show the code that fails.

13:03 {newbie}: (defstruct news :title :date :author :body :link :feed)

13:03 [nil (new :author) (new :title) (new :body) (new :link) (new :date) (new :feed)])

13:03 Chousuke: that's completely wrong :)

13:03 {newbie}: I'm a {newbie} :p

13:04 Chousuke: new is for java classes

13:04 {newbie}: X| so simple

13:04 it is not highlighted in my editor

13:04 thanks!

13:04 Chousuke: (def newnews (struct news title date author body link feed))

13:05 gnuvince: ~s def defstruct

13:05 clojurebot: Excuse me?

13:05 gnuvince: mange un char

13:05 Chousuke: structmaps are popular for some reason.

13:05 I guess they serve as documentation for the map keys.

13:05 Chouser: they are! But I hardly ever use them. I wonder what I'm missing.

13:06 stuartsierra: I never use them either.

13:06 Chousuke: and sometimes I guess someone might even use the accessors!

13:06 Chouser: oh, I never ever make those

13:06 {newbie}: I used then because this data is going to be saved to the database

13:06 rhickey: that's because you guys are old-school Clojurian's, pre structmap

13:07 {newbie}: and if the order is wrong the world get's blown up

13:07 Chouser: I don't think I'm *that* old-school.

13:07 Chousuke: order? do struct maps have order? :/

13:07 {newbie}: no

13:07 stuartsierra: I always kind of felt that structmap was a premature optimization. :)

13:07 Chouser: Chousuke: yes!

13:07 rhickey: when I was learning Clojure we didn't have no stinkin' structmaps sonny... :)

13:08 Chouser: Dec 16 2007 -- first cut PersistentStructMap

13:08 {newbie}: but with struct they must be created with a specific order

13:08 Chousuke: rhickey: until you made them :(

13:08 Chouser: I wouldn't pick up clojure for another 2 or 3 months.

13:08 rhickey: ah, so just stuartsierra

13:09 Chousuke: {newbie}: but how does the creation order matter? :/

13:09 rhickey: I didn't realize they were that old

13:09 {newbie}: btw I have a question about style, I have a method that converts the news to a tuple and a method that converts a single new to a tuple, the method that works on lists uses map.

13:09 Chouser: Chousuke: seqs on structmaps return things in the order that the keys were declared

13:09 {newbie}: Should I use a multimethod instead?

13:10 Chousuke: Chouser: ah, neat.

13:10 Chouser: Dunno if that's promised, but they do currently.

13:11 Chousuke: {newbie}: multimethod? nah.

13:11 {newbie}: So my approach is fine?

13:12 Chousuke: {newbie}: if you have a news->tuple function that converts a news map into a tuple, then (map news->tuple seq-of-news) is better than overloading news->tuple for sequences.

13:12 cemerick: heh, we use structmaps *everywhere*

13:12 slashus2: rhickey: I know this is far less important than your current work, but what is your opinion on this issue? http://groups.google.com/group/clojure/browse_thread/thread/a767baaa0b3b17eb

13:12 Chousuke: assuming I understand what you mean.

13:12 {newbie}: you did :D

13:13 rhickey: slashus2: already removed count inlining here - I'll put it up

13:13 slashus2: Not keen on creating function signatures for (int int) (float float) etc.?

13:13 clojurebot: for is not a loop

13:13 Chousuke: {newbie}: you should use multimethods if you need to handle many kinds of input data each with a similar result

13:14 rhickey: slashus2: maybe, but that is not on deck right now

13:14 slashus2: agreed

13:14 Would you like me to create an issue?

13:14 Chousuke: {newbie}: so an anything->tuple might be a good candidate for a multimethod; then you could even transform a seq of anythings with just (map anything->tuple seq-of-things)

13:14 rhickey: if you have a CA you can submit a patch

13:15 Chouser: what's a tuple?

13:15 I mean, in clojure.

13:16 slashus2: I will mail in my CA.

13:17 {newbie}: Chouser: in my case it's a list

13:17 clojurebot: Who??

13:17 gnuvince: Chouser: a term used to designate a sequence of things that is supposed to have a fixed length.

13:17 Chousuke: Chouser: maybe he has a java Tuple class or something.

13:17 Chouser: {newbie}: ah, thanks.

13:18 {newbie}: the sql lib has a method to insert multiple rows it accepts lists

13:18 i mean't vectors

13:18 Chousuke: {newbie}: in that case you can make a tuple out of your news with just (vals news) :p

13:18 or (into [] (vals news)) for a vector

13:18 {newbie}: :|

13:18 Chouser: (vec (vals news))

13:19 {newbie}: dam I'm felling stupid now

13:19 Chousuke: I prefer (into [] ...)

13:19 Chouser: {newbie}: nah, it's extremely common to re-write several builtin functions when starting.

13:19 Chousuke: {newbie}: though it assumes that the structmap really does return key-val pairs in the order you specified

13:19 Chouser: Chousuke: why?

13:19 {newbie}: are the vals garantee to be ordered by teh key order where I define the strct?

13:20 Chousuke: Chouser: if it's going into the database lib, it probably wants the order the columens are defined in the db.

13:20 columns, too

13:20 Chouser: Chousuke: but vec uses the order of the seq given to it, so ... ?

13:21 Chousuke: Chouser: ah, I didn't mean only your solution; I meant mine too (after all, they're equivalent)

13:21 (into [] ..) is just more explicit so I like it.

13:21 Chouser: ah, I see, sorry. I meant "why do you prefer (into [] ...)"

13:22 oh, ok.

13:22 rhickey: A struct map will retain its base keys in order.

13:22 http://clojure.org/data_structures

13:23 * rhickey wishes he had a good community-supplied demo for Tuesday...

13:23 {newbie}: nice thanks!

13:23 Chouser: wow, that's coming up fast.

13:23 Chousuke: :/

13:24 I assume "vec" predates into?

13:24 stuartsierra: other way around, I think

13:26 jkantz: is there a release of clojure-contrib that goes with the release clojure-1.0.0?

13:26 technomancy: jkantz: nope

13:27 Chouser: man, we're all just lazy bums. no clojure demo, no clojure-contrib release, nobody volunteering to write chunked hashmap seqs

13:28 stuartsierra: Speaking for myself, I'm a busy bum. :)

13:28 technomancy: Chouser: I think you'd make a good contrib manager. =)

13:28 Chouser: technomancy: well if it needs is a very hand-off manager, then maybe...

13:29 Chousuke: I really have no idea what would make a good clojure demo.

13:29 technomancy: I saw a lib was removed from contrib a few days ago since it just plain didn't work any more. I'm glad that's happening.

13:30 stuartsierra: Yeah, I've been trying to clean up stuff I wrote a long time ago.

13:30 Next I need to reorganize my individual library tests to be part of test_contrib

13:31 technomancy: stuartsierra: was looking at your hadoop integration in altlaw yesterday

13:31 stuartsierra: cool

13:32 technomancy: looks like you've got a nice way to abstract all the insane hadoop bits away and deal with it pretty functionally

13:32 stuartsierra: That was the idea. Not perfect yet, but easier than writing Hadoop jobs in Java.

13:32 cemerick: stuartsierra: speaking of contrib and tests, a suggestion: after reading the docs for the testing macro, I thought each child form in the testing body would be wrapped with is, but that's not what happens...

13:33 (testing "foo" (= blah (foo))) evals the equality, but doesn't assert it.

13:33 stuartsierra: That's correct.

13:33 'testing' is just for documentation

13:33 cemerick: that's fine, but the docs say "...which takes a string followed by any number of 'is' assertions".

13:34 stuartsierra: Oops, need to change the example. I'll fix that.

13:34 cemerick: yeah, that was my only point :-)

13:34 rhickey: Chouser: I didn't mean to imply that

13:34 Chouser: rhickey: oh, I wasn't taking it personally. It's just the nature of these things.

13:35 everybody's working on what they want to do, not what anybody else wants them to do. And maybe it's better that way in the long run, dunno.

13:35 rhickey: I had thought we'd all be assigned the same task, like last year, which would have been more of a can you help me do X rather than an open-ended - got anything neat?

13:36 but it ended up being open

13:36 cemerick: stuartsierra: are is awesome, too. Though, it would be handy to have something that does wrap every child form with is. Right now, (are (= _1 _2) ...) does that just fine, but that particular template seems so typical that a top-level macro would be handy.

13:36 rhickey: so I don't know how it will serve as a competition, no apples to apples

13:37 Chouser: fwiw, I can recommend *not* taking a group of java and c++ devs through 600 lines of clojure wrappers around protobuf and Socket as their first exposure.

13:37 cemerick: rhickey: I would have tried to put something together using processing (which I've been experimenting with for work), but I've had my back against the wall since ILC :-(

13:37 Chouser: did that wednesday, and although it went fine I don't think they were exactly wowed.

13:38 * technomancy doesn't begin to understand the mindset from which the average JavaOne attendee would be coming

13:38 cemerick: technomancy: indeed -- I happened to listen to a "is java unproductive today" roundtable on the java posse podcast on the drive in today. It was a sad display, IMO.

13:39 technomancy: in the Programming Clojure book there's an example of a "code snippet" mini-web app in just a few pages

13:39 cemerick: lots of "it'd be so great to get an elvis operator in the next version of java", etc

13:40 technomancy: but I guess we didn't want the demo to be a web app

13:41 alinp: hi

13:41 http://pastie.org/494198

13:41 having this code

13:41 marklar: Does the development process count as 'something cool about the language'? I know coming from Java/C# the best part for me has been the Repl and the ease of development

13:42 alinp: why is getting this error: Exception in thread "main" java.lang.IllegalArgumentException: Argument is not an array (ringclbg.clj:0)

13:42 ?

13:42 technomancy: marklar: yeah, but if you're being pitted against other dynamic JVM languages they will all take that for granted

13:42 alinp: I can't see what is wrong there

13:42 marklar: technomancy: ah, I guess I should look what other languages are included :)

13:42 Chouser: cemerick: well, that's a thought. show some code that wants an elvis operator ... then writing fricking elvis macro.

13:42 technomancy: not that slime isn't more advanced than IRB, but it's not a core strength

13:43 dnolen: technomancy: it's subtle to explain the power of the REPL over something like IRB or python interactive mode.

13:43 cmvkk: alinp, aset takes an array as a first argument, but "ring" isn't an array

13:43 it's just a list.

13:43 dnolen: python interactive mode sucks, it can't even handle updating imported libs.

13:43 irb sounds better, but it doesn't seem good to leave open the way you do with lisp projects.

13:44 Chousuke: why are you using an array in the first place? doesn't look like you need one :/

13:44 clojurebot: Lisp isn't a language, it's a building material.

13:44 technomancy: cemerick: the whole, "let's patiently hope that Sun does this neat thing in the next release" rather than "let's hack out an experiment and see if it ends up being a net win" mindset... I just don't know what to make of it.

13:44 alinp: I see

13:44 technomancy: utterly foreign

13:44 alinp: well ... someone used it

13:44 and I modified the code a little bit

13:44 and it seems that I did wrong

13:44 so, it's about that

13:44 thanks

13:44 I'll see what I can do

13:44 Chousuke: you want the agent with 0 at the end of the array? :/

13:45 alinp: mno

13:45 in fact is my fault that I did copied the code without knowing exactly what it does

13:46 yes, I don't need that

13:46 for sure

13:46 I'll delete it and write it my own implementation

13:46 Chousuke: because you can create a vector of agents like so: (into [] (for [i (range 10)] (agent i)))

13:47 alinp: thanks Chousuke & cmvkk

13:47 well ... I can create a list of agents .... (def ring (repeat ring-size (agent nil)))

13:47 it's easier, right ?

13:47 Chousuke: yeah, except it's lazy

13:47 alinp: I don't need a vector, at all

13:47 cemerick: Chouser: yeah, maybe. I honestly don't know what to say to a crowd that is currently at or below that level, though.

13:47 cmvkk: by the way, that only creates a list of the same agent over and over again.

13:47 alinp: the list, or the vector ?

13:47 the vector, right ?

13:47 Chousuke: the list

13:48 cmvkk: if you want n different agents, you want something like (take ring-size (repeatedly #(agent nil)))

13:48 alinp: .......

13:48 Chousuke: it's not a list at all, actually

13:48 alinp: hmmm

13:48 Chousuke: it's a seq

13:48 cemerick: e.g. you'll say macro, and they'll roll their eyes thinking about C macros or something.

13:48 alinp: it's a seq ?

13:48 well , I didn't said that it's a lazy seq

13:48 Chousuke: yeah.

13:48 (doc repeat)

13:48 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

13:48 alinp: shouldn't I specify it's lazy ?

13:48 oh

13:48 crap

13:48 right

13:48 cemerick: technomancy: there is a very large population that wants java to stay exactly the same....and continue to use it as is. *shrug*

13:49 alinp: so, what's wrong with that ? :)

13:49 I want it to be lazy

13:49 ataggart: cemerick: that depends on precisely what you mean by "stay the same"

13:49 technomancy: cemerick: luckily for them, Java 1.6.0_10 _will_ stay the same.

13:50 Chousuke: alinp: well, if you make a lazy seq of agents, you won't actually have them until you read them from the list somewhere :p

13:50 alinp: I'll do read them

13:50 ataggart: changes to the underlying capabilities of the VM is one thing, slapping on more "stuff" into the Java language itself is another

13:50 cmvkk: Chousuke, that would be okay i think, becuase you can't send to them unless they exist already

13:50 alinp: that's why I said that I'll write the code myself

13:50 instead of the old one

13:50 cemerick: ataggart: I can't pretend to know the full argument from that side. One of the big sticking points in the discussion I listened to was "learning new language features is simply too hard and time-consuming".

13:50 {newbie}: how was the world before structmap btw?

13:51 Chousuke: {newbie}: you just used regular maps, I guess :p

13:51 * durka42 dusts off the ancient history books

13:51 cemerick: technomancy: heh, we still get people emailing asking if we support java 1.2, sometimes 1.1.7

13:51 ataggart: my view at this point is Java is... sufficient. If you want a different set of features, pick a new JVM language.

13:51 a la clojure

13:53 Chousuke: cemerick: and about the macro thing... I guess you could just say you can make functions that run at compile time

13:53 and generate more code

13:53 cemerick: Chousuke: maybe.

13:53 {newbie}: well I'm learning clojure for a project with just a few weeks for the deadline

13:53 ataggart: a lot of java devs won't know what a macro is anyway

13:53 Chousuke: so that if you end up with a boilerplate pattern, you can write a compile-time function that generates that boilerplate pattern for you

13:54 cemerick: {newbie}: welcome to the 5%-club :-)

13:54 Chousuke: and since clojure code is data, there will be no string handling involved!

13:54 {newbie}: :P I won't touch on macros

13:54 yet

13:54 technomancy: wise

13:54 * cemerick is not feeling very populist today

13:54 Chousuke: most of the time you don't need them, anyway

13:55 other than what the core libraries already provide, of course.

13:55 ataggart: or if you do, it's already been written by someone else

13:55 cemerick: I'd agree with whoever suggested it that the best demo is the workflow. Use a mainstream environment (one of the plugins for NB, Eclipse, IntelliJ), and code stuff up at runtime, without an edit, compile, run cycle.

13:56 FWIW, of course. I'd have a lot more weight if I had put together a shiny demo. :-/

13:56 * technomancy found a socket server to be a good demo since it's about the simplest interactive thing you can put together that requires concurrency

13:56 technomancy: everyone understands telnet, and there's less overhead to explain than HTML-generation

14:02 with mire I had a multiplayer text adventure working in < 60 LOC. that could make a good demo.

14:03 Chousuke: heh

14:04 wonder if the audience has laptops. would probably impress them if they could join the game themselves.

14:04 technomancy: depends more on if the wifi holds I suspect

14:05 don't know about JavaOne, but conference wifi is usually sketchy

14:05 but yes, that would be pretty cool.

14:05 * Chousuke remembers an CS freshman intro lecture where the lecturer opened irssi on the projector and a bunch of people from the lecture hall joined the channel :P

14:07 Chousuke: it was also fun sending local mail on the school unix server when the mail system was demoed.

14:07 hiredman: technomancy: I assume JavaOne is Enterprise Ready(TM(TM)

14:07 Chousuke: no need for pesky @ signs :)

14:11 slashus2: ,(* (int 2) (int 356666666666666666666))

14:11 clojurebot: -1029352108

14:11 slashus2: ,(* (int 2) (int 3566666666666666666))

14:11 clojurebot: java.lang.ArithmeticException: integer overflow

14:12 Chousuke: ,(class 356666666666666666666)

14:12 clojurebot: java.math.BigInteger

14:12 Chousuke: ,(int 356666666666666666666)

14:12 clojurebot: -514676054

14:13 slashus2: Seems like the first one should give an integer overflow too.

14:13 Chousuke: probably.

14:14 durka42_: ,(int 3566666666666666666)

14:14 clojurebot: -1293636950

14:15 ataggart: ,(class (int 356666666666666666666))

14:15 clojurebot: java.lang.Integer

14:15 durka42: i wish colloquy would do that automatically

14:16 so int doesn't check for integer overflows, but * does

14:16 emacsen: I asked this a few days ago and I think I was misunderstood...

14:16 durka42: i guess in the first case, the conversion from int overflows but * doesn't, and in the second case the conversion from int overflows, but the multiplication overflows again (in the other direction)

14:16 emacsen: Is there a method that I can run on an object (or a class) that will give me a list of methods availalble for it?

14:17 durka42: c.c.repl-utils/show

14:17 emacsen: eg if I pass it a list, it will return sort, first, rest

14:17 durka42: scratch that

14:17 show is not quite that smart

14:17 emacsen: durka42: Well repl-utils doesn't work for me. It doesn't build properly, and secondly, as that was the suggestion people gave me last time, that's not what I want, show. :)

14:18 durka42: i guess that's hard to do without types :)

14:18 emacsen: it doesn't build?

14:18 emacsen: durka42: Not AFAICT. It doesn't import at least

14:18 durka42: ah, well you don't import clojure libs, you use or require them

14:18 emacsen: the NS is there but it doesn't work

14:18 slashus2: durka42: Is that the correct behavior for *?

14:18 emacsen: sure, okay, require

14:18 Chousuke: emacsen: the problem is that clojure functions don't have type information by design (except maybe a type tag... sometimes)

14:18 emacsen: but contrib.math works

14:19 Chouske: how does CL do it?

14:19 durka42: slashus2: define "correct"

14:19 emacsen: you can ask CL for this... I forget how but I know you can

14:19 Chousuke: I have no idea.

14:19 slashus2: Was it designed to behave that way.

14:19 durka42: ~bat signal

14:19 clojurebot: /summon Chouser

14:19 durka42: hmm, no, the other one

14:20 has this been discussed on the group?

14:21 slashus2: Are you talking to me?

14:21 Chousuke: emacsen: it'd be quite difficult to figure out in general what a function can consume

14:21 durka42: slashus2: yeah

14:21 slashus2: No. I was playing around with math operations, and discovered this behavior.

14:22 durka42: http://clojure.org/news seems to suggest ("integer arithmetic should not silently produce corrupt values due to overflow") that the behavior of int is wrong

14:22 on the other hand, casting to int isn't really arithmetic

14:23 Chousuke: yeah, but using primitive ints should still raise exceptions :/

14:23 and it does; so I think the cast should too.

14:24 slashus2: I will bring it up in the group.

14:24 durka42: (isa? 3M Number)

14:24 ,(isa? 3M Number)

14:24 clojurebot: false

14:24 durka42: ,(isa? 3M BigInteger)

14:24 clojurebot: false

14:24 Chousuke: I think it goes the other way

14:25 durka42: ,(instance? BigInteger 3M)

14:25 clojurebot: false

14:25 Chousuke: hmm

14:25 ,(class 3M)

14:25 clojurebot: java.math.BigDecimal

14:25 durka42: ,(instance? Number 3M)

14:25 clojurebot: true

14:25 durka42: (.intValue 3M)

14:25 ,(.intValue 3M)

14:25 clojurebot: 3

14:26 durka42: ,(.intValue 3566666666666666666)

14:26 clojurebot: -1293636950

14:26 durka42: but that was a long, not a BigDecimal

14:26 ,(.intValue 3566666666666666666M)

14:26 clojurebot: -1293636950

14:26 emacsen: Chouske: http://lisp.org/mop/dictionary.html#specializer-direct-generic-functions is sorta what I'm talking about

14:27 ataggart: so, the reason the first one "worked" and the second threw an exception is because in both cases the args were wrapped, but the result of * in the first case didn't wrap, wheeras it would have wrapped in the second?

14:28 Chousuke: emacsen: hm

14:28 emacsen: I don't think that does what you think it does. or maybe I don't know what you think it does.

14:29 durka42: ataggart: i think so

14:30 emacsen: a friend showed me it can /sorta kinda/ do what I want

14:30 but it's not pefect, that's true. I just see it as an impediment. You have to keep the reference docs open a lot, I'm finding

14:30 Chousuke: so what does it actually do?

14:31 how do you call it? :/

14:31 emacsen: I'm getting my more CL knolwedgeable friend to come and explain it

14:31 I, in truth, have never used it :)

14:32 technomancy: emacsen: generics are a different thing; I don't think that would work for normal functions.

14:32 Chousuke: aren't the specialisers limited for generics in CL?

14:32 or am I misunderstanding if I think it means the dispatch functions you can use

14:33 emacsen: technomancy: In truth I did so little CL I never used CLOS

14:33 * Chousuke doesn't remember much of CLOS

14:33 emacsen: so maybe my solution is wrong, but I can't think of a solution

14:34 technomancy: that's because CLOS is ... hard to remember

14:34 Chousuke: the dispatch function for clojure's multimethods is arbitrary, but I guess you technically could look up multimethods if you have the actual function object used as the dispatch :P

14:34 ataggart: emacsen: what problem are you trying to solve?

14:35 slashus2: ataggart: I figured out the problem

14:35 In Numbers.java multiply with the signature int int does an overflow detection.

14:35 emacsen: I'm finding the reference docs a bit... scattered

14:35 slashus2: it tests if y != 0 and if ret/y != x

14:35 emacsen: and so it'd be nicer/easier if I could simply ask a function for help

14:36 Chousuke: well, there's find-doc

14:36 ataggart: and regular doc

14:36 slashus2: In this rare case ret/y is equal to x ret: -1029352108 x: 2 y: -514676054

14:36 emacsen: doc is useless as you have to know the method you want

14:36 slashus2: ,(/ -1029352108 -514676054)

14:36 clojurebot: 2

14:36 Chousuke: find-doc isn't :)

14:36 it takes a regexp

14:37 slashus2: Does that make sense?

14:37 emacsen: Chouske: true. What would also be very nice would be a find-doc that could operate over every NS in your classpath

14:37 ataggart: someone needs to start a clojure.contrib.esp project

14:37 Chousuke: the reference on the web page is pretty well interlinked nowadays at least.

14:37 emacsen: Chouseke: yeah... it's gotten better. It should also be doownloadable :)

14:38 Chousuke: emacsen: I don't think that's possible in a practical manner.

14:38 emacsen: Chouseke: downloadable docs are impractical?

14:38 Chousuke: no, I mean searching the entire classpath

14:38 you need to (require) stuff to get the metadata.

14:38 emacsen: I've seen many people rewrite stuff in contrib

14:38 technomancy: you could write a spider that could auto-require stuff if you didn't mind bloating memory usage

14:39 Chouser_: I suppose you could grep the classpath. :-P

14:39 technomancy: in fact, it'd probably be three lines of code using file-seq

14:39 Chousuke: emacsen: rewrite?

14:39 emacsen: usually they rewrite the functions poorly too ;)

14:39 technomancy: then find-doc would work

14:39 emacsen: Chouske: they need something that's already written

14:39 Chousuke: ah, right.

14:39 they should use the doc index on the site!

14:40 :P

14:40 http://code.google.com/p/clojure-contrib/wiki/ApiDocIndex there :)

14:40 emacsen: Chouseke: Maybe you're right that my original idea was poor but the docs should be easier to search... and search offline :)

14:41 even if that's with a separate tool ala pydoc

14:41 Chousuke: hmm

14:41 well, that shouldn't be too difficult

14:41 they ARE already generating the wiki markup after all

14:41 emacsen: and the scope is certainly less

14:41 ataggart: my browser lets me save webapges...

14:41 emacsen: attaggart: My editor lets me save browsers ;)

14:41 Chousuke: shouldn't be too difficult to adapt it to generate something else.

14:42 emacsen: Chouseke: yeah I should read find-doc and see if there's a simple way to generate a meta-index of terms

14:42 technomancy: emacsen: (map load-file (filter #(re-find #"\.clj$" %) (map #(.getPath %) (file-seq (java.io.File. "src/clj/clojure-contrib/src")))))

14:43 then find-doc will work over all contrib

14:43 emacsen: fair nuff :)

14:44 Chousuke: emacsen: there's gen-html-docs.clj in contrib too

14:44 * technomancy notes that snippet could be shorter if regexes were functions

14:44 emacsen: Chouske, but no one knew about it :-P

14:44 Chousuke: though is that actually the script used to generate the wiki docs? :/

14:48 emacsen: well, that solves the problem enough, having docs

14:52 BTW, since I heard about them in the interview, are these "ports" official?

14:52 clojurescript and the C# one?

14:52 technomancy: what does "official" mean?

14:52 emacsen: Well, good question

14:52 What is a Clojure? :)

14:52 is there a test suite?

14:52 technomancy: Clojure is still implementation-defined.

14:53 the test suite is ... not a high priority.

14:53 to put it kindly

14:53 emacsen: well a test suite is important when you want to define the API

14:53 Chouser_: implementation-defined, for an open source project, is Good.

14:53 emacsen: Chouser: for a while. then it's bad :)

14:53 technomancy: especially at this stage

14:53 emacsen: yes, at this stage

14:53 Chouser_: what makes it become bad?

14:54 emacsen: Chouser: multiple implementations

14:54 look at, say Python. There are seven or eight Pythons

14:54 ataggart: clojure.org <-- that one

14:54 emacsen: but you can know how complete they are by how they perform the test suites

14:54 ataggart, then why would Rich mention the others?

14:54 unknown_lamer: emacsen: so what I am supposed to explain hrm?

14:55 emacsen: unknown_lamer: the discussion's over. There's no good way to do it

14:55 ataggart: cuz he was asked a question about it. Some people have an aversion to the JVM

15:03 Chousuke: emacsen: the lack of a spec is both a blessing and a curse

15:04 and I don't think the ports are in any way official

15:05 though it'll be an interesting problem to solve if at some point you'd like compatibility between a .NET clojure and the JVM clojure.

15:06 but the tight integration with the host platform makes that non-trivial.

15:07 ataggart: if the effective evidence of compatibility is something written for one can run on the other, then I imagine you won't ever get it between JVM and .NET clojures

15:07 emacsen: Yeah that's why I asked why bring up unofficial ports. It's like opening the perverbial pandora's box

15:07 hiredman: anyone know anything about the new G1 garbage collector? like what the deal is with "production use of G1 is only permitted where a Java support contract has been purchased."

15:07 Chousuke: ataggart: well you could, if you don't use host interop

15:07 technomancy: hiredman: it means Oracle's Reign of Terror has begun.

15:08 hide you women.

15:08 emacsen: technomancy: You mean "your"?

15:08 ataggart: chousuke: my point is the interop is inherent to clojure

15:08 hiredman: http://java.sun.com/javase/6/webnotes/6u14.html

15:08 technomancy: emacsen: yes

15:08 emacsen: or "You, women, hide!" ;)

15:08 technomancy: actually both work.

15:08 Chousuke: ataggart: well, kind of.

15:08 hiredman: -XX:+DoEscapeAnalysis looks juicy

15:08 Chousuke: ataggart: you *could* write wrappers for it all.

15:08 hiredman: go ahead and do a benchmark!

15:09 hiredman: Chousuke: :(

15:09 Chousuke: (I can't, I'm on OS X with not u14 ;()

15:09 * danlarkin wishes he were running java6

15:09 Chousuke: the latest java for OS X is... u13

15:10 hiredman: heh

15:10 I think the only place I can run the latest ins my shiny new (delivered today) vista desktop at work

15:10 ataggart: I'm on a 32-bit OS X... no java 6 for me.

15:10 technomancy: do openjdk versions get numbered differently than sun's?

15:11 Chousuke: ataggart: PPC or older intel? :/

15:11 ataggart: intel

15:12 I'm just waiting for the new macbook pro to be released, then I'll be set

15:12 slashus2: This isn't the fault of the multiply function. The argument has already overflown by the time it reaches the multiply method. Maybe adding overflow detection to the coercion functions?

15:12 ataggart: slashus2: the (int... is you saying you want the overflow

15:13 or rather, are willing to have it for the sake of speed

15:13 slashus2: When you coerce something with int maybe it could give you an overflow exception if it overflows?

15:13 Chousuke: ataggart: are you sure? operations with the cast int DO throw exceptions.

15:13 jlb: Hey all, I'm pretty new to Clojure, and I've run into a casting issue... I have a javax.naming.InitialContext instance which I'm using to look up a remote EJB interface... in Java, I cast the return value to the interface class of the EJB... this doesn't work in Clojure, or at least not the way I'm trying to do it.

15:13 Chousuke: ataggart: there's unchecked-add etc. for when you don't want them

15:14 slashus2: Chousuke: I found a fringe case where the overflow detection fails.

15:14 jlb: In particular, (cast foo.bar.InterfaceName x) throws a ClassCastException

15:14 Chousuke: that's a separate bug I think :)

15:15 ataggart: iirc, numberc values will get autopromoted, unless you say something like (int...), and matematical operations on real ints which would result in the answer being wrapped will throw an exception

15:15 Chousuke: jlb: cast doesn't actually do anything

15:15 ataggart: and iirc, there's a way to turn even that excpetion stuff off

15:15 Chousuke: jlb: it just checks if x is of the said interface.

15:16 jlb: Chousuke: understood, but it is the simplest test indicative of the problem

15:16 slashus2: Chousuke: I don't think so. The multiply function does all it can to see if it's result is overflown, but if it gets an argument that has been coerced by int (and overflown) or something, an unexpected number could be sent to the multiply method.

15:17 Chousuke: ah, of course. so there needs to be an overflow check in the int cast :/

15:17 slashus2: right

15:17 I think it needs it to live up to the promise of correct math.

15:18 technomancy: clojurebot: math?

15:18 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

15:18 jlb: the lookup returns a proxy object which I don't fully understand all the inner workings of, but I can cast it in Java but not in Clojure

15:18 technomancy: clojurebot: math is hard.

15:18 clojurebot: c'est bon!

15:18 ataggart: but you're asking for possibly non-correct *values* by forcing it to be an int

15:18 Chousuke: ataggart: I think the docs say that operations on (int foo) are still checked; just not boxed.

15:19 slashus2: ataggart Surely I don't want it to overflow though.

15:22 hiredman: jlb: clojure is a dynamic language, casting is generally not something to care about

15:22 ataggart: chousuke: nope, only mathematical operations are checked

15:22 hiredman: just call your methods

15:22 ataggart: 'int just does a java (int) cast

15:23 jlb: hiredman: well that's my problem, I do that and I get a ClassCastException (trying to just call them)

15:23 hiredman: jlb: pastebin some code

15:25 lisppaste8: url

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

15:25 hiredman: jlb: you might just need to type hint with the correct class

15:25 ataggart: and for Numbers (i.e., non-primitive numeric types), it calls intValue(), which is specified to behave as it does for primitives, namely overflowing.

15:25 jlb: hiredman: will do

15:25 hiredman: I think there is (or was) an issue with private classes

15:26 jlb: hiredman: tried that, didn't work, though it's possible I screwed it up

15:26 hiredman: not being able to reflect properly on them

15:26 slashus2: ataggart: I see.

15:28 ataggart: not checking on 'int seems a reasonable thing to me, since the intent id speed and you generally don't cast to int after already having a large number.

15:28 hiredman: jlb: have you run (class ...) on whatever to see what class it is?

15:29 slashus2: ataggart: Moral of the story is. Don't cast a large number to an int. Rely on the mathematics operations to check for overflow?

15:29 ataggart: ya

15:29 which is probably what's happening anyway

15:30 larger numbers as a result of mathematical operations. typically you'd cast to int before such ops

15:30 hence you'll get an exception

15:30 slashus2: fair enough

15:31 jlb: hiredman: http://pastebin.com/m49b0f7d9

15:35 hiredman: jlb: can you paste the exception output somewhere too?

15:37 jlb: hiredman: yep - http://pastebin.com/d855920d

15:38 hiredman: thats the whole exception?

15:38 jlb: I'm going to guess I can make it work by writing some java on the client side and returning the cast-ed interface from it, but seems like it "should" work in Clojure directly

15:38 yep

15:39 ataggart: (PortableRemoteObject/narrow foo MyClass)

15:39 hiredman: what is the method signature for lookup?

15:40 jlb: Object lookup(String)

15:40 ataggart: jib: have you tried using PRO.narrow ?

15:40 alrex021: Is there an up to date off-line version of the Clojure reference? (pdf or html format)

15:41 ataggart: alrex021: for html, your browser probably lets you save webapges

15:41 jlb: ataggart: trying that now

15:43 ataggart: same exception

15:43 ataggart: hm

15:43 and the java verions is working?

15:43 jlb: yep, been using it for months :)

15:43 alrex021: ataggart: would be really cool if it was downloadable so the html links work nicely.

15:45 ataggart: jib: what's the result of (ancestors (class foo)) ?

15:45 rich_holygoat: afternoon folks

15:45 anyone going to Java One have a Refer A Friend code they'd like me to put in my registration?

15:46 rodgertq: holy goat, is that like a regimental goat?

15:48 jlb: ataggart: #{java.lang.Object java.io.Serializable org.jboss.ejb3.JBossProxy java.lang.reflect.Proxy foo.bar.FooEJBRemote}

15:48 rich_holygoat: rodgertq: heh. it's a pun :)

15:48 ataggart: and foo.bar.FooEJBRemote is the class you've been trying to cast to?

15:49 jlb: right

15:49 ataggart: that's messed up

15:49 jlb: (it's an interface)

15:49 ataggart: ya

15:49 my first EJB project was in 2000

15:49 ols skool

15:50 dnolen: Google Wave Server is written in Java, that will be fun to code against with Clojure

15:50 jlb: I'm relatively new to it (1 year). Seems like things used to be a lot more painful. :)

15:50 dnolen: http://groups.google.com/group/google-wave-api/browse_frm/thread/a12aa99aa83ee7f9

15:52 ataggart: jib: the only other thing I can think of is either that class is not in the classpath (doubtful) or that its from a different classloader

15:52 not in the classpath would be a different excpetion, so ya not that

15:53 I thought PRO.narrow handled the classloader issue

15:53 jlb: ataggart: right, I ran into that... it seems that the Repl doesn't pay attention to CLASSPATH? (env variable)

15:54 hiredman: uh

15:54 classpath is handled by java

15:54 if you launch java with the -cp flag java ignores the CLASSPATH environment variable

15:55 triddell: dnolen: I'm just finishing yesterdays presentation now... very interesting.

15:57 jlb: hiredman: that's what I thought, but I installed jline and clojure in the java extensions folder, so they get picked up automatically... my command line to run the Repl is: java jline.ConsoleRunner clojure.lang.Repl, so I would expect CLASSPATH to be honored by Java, but I had to (add-classpath) for everything

15:57 hiredman: !

15:58 add-classpath is your problem

15:58 don't ever use it and expect it to work

15:58 ataggart: classpath being not mutable during runtime

15:59 jib: given that one of the ancestors of foo is the class you're trying to cast to, I'd bet it's a classloader problem

16:00 jlb: ok

16:00 I'll try to figure out what is going on w/ CLASSPATH then

16:00 ataggart: (= (getClassLoader (class #{})) (getClassLoader (class foo)))

16:00 try running that

16:00 I bet it'll be false

16:00 hiredman: jlb: you could always just -cp $CLASSPATH

16:03 ataggart: or more appropriately: (= (getClassLoader (class foo.bar.FooEJBRemote)) (getClassLoader (class foo)))

16:04 jlb: is there a canonical way to print the classpath from inside clojure?

16:05 stuartsierra: (System/getProperty "java.class.path")

16:05 dnolen: triddell: yes, I'm thinking about adopting it for one our projects. Google Wave + Clojure.

16:05 Chouser_: The problem has to do with the fact that there's not really just one classpath, I think.

16:05 Each classloader can have a classpath, can't it?

16:06 ataggart: the VM has a classpath

16:06 jlb: So (System/getProperty) returns the right thing

16:06 j-dot: is it possible to call new with the result of an expression?

16:06 ataggart: but classes emitted by different classloaders are not equivalent

16:06 j-dot: e.g. (new (type []))

16:06 I mean to say, is there some way to do the equivalent?

16:09 ataggart: if the returned value is a Class, then (.newInstance c)

16:09 Chousuke: ,(.newInstance (class []))

16:09 clojurebot: java.lang.InstantiationException: clojure.lang.PersistentVector

16:09 Chousuke: hmm

16:09 I guess it needs parameters

16:09 ataggart: no public constructor

16:10 Chousuke: ah, heh

16:10 ataggart: erm, well

16:10 wow it's hard to read this non-standard java

16:10 Chousuke: non-standard?

16:10 j-dot: hmmm ...

16:10 ataggart: not a criticism, but it's just... differently written

16:10 jlb: So if I run java with -cp /path/to/foo-api.jar, it fails to find FooEJBRemote when I try to import it... I must not be understanding something.

16:10 Chousuke: you nean the clojure source code?

16:11 ataggart: chousuke: ya

16:11 Chousuke: it has peculiar style

16:11 but at least it isn't like the iTerm source code :P

16:11 ataggart: ok, no arg constructor is protected

16:11 so ya

16:12 Chousuke: the whole project could use a =G in vim for all its files.

16:12 ataggart: ,(.newInstance (class "test"))

16:12 clojurebot: ""

16:12 ataggart: ta-da!

16:12 j-dot: jlb: is that your full classpath, just the one jar?

16:12 thanks ataggart

16:13 jlb: j-dot: no, but now I'm trying to eliminate possibilities... I should NOT get a ClassNotFoundException for FooEJBRemote, correct? (even if it depends on something else which isn't found?)

16:14 (If something isn't found, I should get an exception for the not found thing?)

16:14 ataggart: CNFE means something is missing from the classpath, CCE means different classloaders (or just a real error)

16:14 j-dot: jlb: no, I don't believe you should .... right, the exception should be for the missing thing

16:15 ataggart: yay! I can contribute to #clojure :)

16:15 Chousuke: :p

16:15 got a CA in?

16:15 jlb: ataggart: right... I think you're right about the classloaders, and perhaps using (add-classpath) caused that problem... so I'm now trying to figure out why it doesn't see my classes based on CLASSPATH (or -cp)

16:16 ataggart: just so I'm clear on the context, you have an ejb server runing somewhere, and you're using the repl to act as a client to that server, right?

16:16 jlb: (I'm in the same directory that my plain Java code is built in, with the same classpath, etc... so the classpath should "just work")

16:16 ataggart: erm, no

16:16 once you us e-cp, the current directory isn't automatically used

16:17 jlb: ataggart: right... I have a long and annoying Java client for exercising various things, and it would be much better to use clojure :)

16:18 ataggart: it's been a while since I've written java that *didn't* run inside a server setup

16:19 so -cp ./:clojure.jar:jline.jar:ejb.jar:other-libs.jar

16:19 your cp looks something lke that right?

16:21 jlb: I stuck jline and clojure in the existing java classpath (/Library/Java/Extensions on the Mac) ... so my CLASSPATH (or -cp, I've done both) includes all of the ejb stuff and my ejb-client jars

16:22 ataggart: ugh

16:30 technomancy: is anyone using hbase and/or capjure?

16:30 I spend a day earlier this week trying to get it going with disappointing results; would love to hear some awesome stories about it that could get me motivated as I try again.

17:11 duck1123: Does anyone know if it's possible to kill a slime connection without killing all of the connections?

17:12 if I try to kill it from the *SLIME Connections* buffer, it kills the server

17:13 and if I M-x slime-disconnect, it disconnects all of my connections

17:16 technomancy: duck1123: I've found it's much easier to stick to one slime connection per emacs instance

17:18 duck1123: technomancy: right, but sometimes I accidentally open a second one, and I want to cut back to just one

17:20 I suppose I could add some logic to my connection fn that checks if I'm connected, but I was just wondering if there was a way if I already have multiples

17:21 technomancy: just find the second *inferior-lisp* buffer and kill it

17:21 that will disconnect you

17:22 hiredman: whats the url for that loop thing?

17:22 duck1123: I'm not using *inferior-lisp*, I'm running a compojure-jetty server and use slime-connect to connect to the running server

17:23 technomancy: duck1123: if you use slime-connect, it creates an inf-lisp buffer in the background

17:23 you just usually don't interact with it, but it's there

17:25 duck1123: ah ha. it's actually ' *cl-connection*' but if I kill that, it'll close just one of the connections, thanks

17:25 slashus2: Do commits run concurrently in clojure? Talking about transactions.

17:27 technomancy: slashus2: I think as long as they don't touch the same refs they should

17:27 slashus2: So transactions working on the same ref are locked?

17:32 duck1123: does it actually use locking? I thought I heard that you didn't need locking with Clojure. Or was it that the STM took care of all of that for you?

17:32 slashus2: I was talking about internally.

17:35 technomancy: slashus2: I don't know if it uses locking internally, the answer rhickey always gives is that you shouldn't care how it works, you should only care about the guarantees it provides

17:35 hiredman: Error: no `server' JVM at `C:\Program Files\Java\jre6\bin\server\jvm.dll'.

17:35 D:

17:35 technomancy: hiredman: your slashes are backwards.

17:35 unless... is it backwards day? /me checks his calendar.

17:35 slashus2: technomancy: Someone is creating a similar STM in CL, and I was trying to figure some internals out for them.

17:35 arohner: could be backwards OS day

17:36 :-)

17:36 technomancy: slashus2: probably no way around reading the source yourself if that's the goal. =)

17:37 slashus2: I was trying to. Just needed to confirm.

17:37 dnolen: slashus2: isn't there CL-STM?

17:38 slashus2: Could be, but I think this other person has slightly different goals.

17:41 duck1123: I would almost bet that there are locks somewhere in the stm impl, which is just where I want them. (as opposed to in my code)

17:47 scgilardi: clojure/src/jvm/clojure/lang/LockingTransaction.java implements the guts of "dosync". It uses locks.

17:48 duck1123: makes sense, I couldn't figure out how you would do what dosync does without using locks somewhere

17:52 slashus2: yes LockingTransaction.java is neat.

17:55 hiredman: how do I install hotspot on windows?

17:55 apparently the 32bit jre for windows does not come with hotspot

17:55 Chousuke: huh

17:56 that would be weird.

17:56 hiredman: not "would", its a fact

17:56 Chousuke: is HotSpot the name for the server jvm then?

17:56 hiredman: yes

17:57 Chousuke: I thought it was the name of the JIT/Interpreter combo

17:57 anyway, perhaps you need the java SDK

17:57 or some enterprisey version :P

17:58 technomancy: hotspot comes in client and server varieties

17:58 Chousuke: hmm, yeah

17:58 "Java HotSpot(TM) Client VM (build 1.5.0_16-135, mixed mode, sharing)"

18:00 hiredman: oi

18:00 Chousuke: (java -server -version gives the other one)

18:00 clojurebot: ?

18:01 Chousuke: ~botsnack

18:01 clojurebot: thanks; that was delicious. (nom nom nom)

18:05 replaca: I have to say I get a warm feeling inside everytime I type ^C-RET in emacs/slime and get a pretty printed macro expansion.

18:07 Chousuke: :)

18:07 certainly helps

18:07 the non-pretty-printed expansions were a bit of a pain sometimes :p

18:08 replaca: I hope Chouser, stuartsierra and others get that feeling lots, since they've added so much

18:24 also, after years of lisp-2s, I *really* like being in a lisp-1

18:24 technomancy: replaca: seriously

18:25 replaca: I never knew the pain I was feeling until it was gone :-)

18:25 arohner: I started playing with CL and scheme around the same time

18:25 I dropped CL *because* it was a lisp-2

18:26 replaca: (let [f (fn [x y] ...)] ...) is bliss

18:26 never got very far into scheme, so this is the first time I've had the joy

18:26 ataggart: I still haven't grokked the difference

18:27 arohner: ataggart: lisp-2s require special syntax to pass fns around

18:27 technomancy: ataggart: it's really awkward to keep functions in variables in lisp-2s

18:27 replaca: ataggart: whether functions live in a different namespace from other stuff

18:27 so you end up with different syntax and idioms around funcs than other things

18:28 Chousuke: also, lots of funcalls :P

18:28 ataggart: hmm... seems kind of antithetical to FP

18:28 replaca: e.g., in CL you need funcall to call a func in a variable

18:28 Chousuke: which aren't very fun at all!

18:28 replaca: ataggart: yeah

18:28 hiredman: "Elapsed time: 52.964274 msecs"

18:28 hmm

18:28 ataggart: well, clojure is my first lisp (not counting reading scheme in SICP)

18:28 Chousuke: hiredman: for what?

18:29 hiredman: Chousuke: the ring thing

18:29 with N = 1000

18:29 Chousuke: where? I haven't been following the channel :/

18:29 hiredman: http://groups.google.com/group/clojure/browse_thread/thread/5e0c078d0ad8b8bc

18:31 Chousuke: that with escape analysis on?

18:31 technomancy: anyone else find that they're avoiding adding docstrings because then the arg list isn't right next to the fn name?

18:31 Chousuke: what about without.

18:31 technomancy: or is that just me?

18:31 hiredman: Chousuke: haven't tried

18:31 I just messing with Queues

18:31 * Chousuke would like to see some benchmarks

18:32 Chousuke: can't do them myself either :(

18:32 would require installing Linux and probably the JVM manually too

18:32 :P

18:32 hiredman: erg

18:33 slowed down

18:33 actually, I think it is about the same, with about 10milliseconds of jitter either way

18:35 Chousuke: maybe 1000 is too small... the JIT won't optimise it.

18:35 eevar: Chousuke: if you're on debian, getting Java is just: aptitude install openjdk-6-jdk -R

18:35 hiredman: well, not a lot of allocation and gc going on in this code anyway

18:35 Chousuke: eevar: will it be the latest version though? :)

18:36 right.

18:36 probably not a good benchmark of escape analysis.

18:36 not that I really know what I'm talking about ;(

18:36 hiredman: mmmm

18:36 eevar: hmm.. I have 6b14-1.5~pre1-5 -- no idea how recent that is

18:37 hiredman: so nice

18:37 eevar: debian testing, tho -- not stable

18:37 hiredman: my machine at work just went from and old p4 laptop to a core 2 quad desktop

18:37 b14 is the latest

18:38 Chousuke: quad core? neat.

18:38 hiredman: it sure is

18:38 Chousuke: now you can have up to three stuck mplayer instances without noticing anything.

18:39 scgilardi: I recall (perhaps incorrectly) from Cliff Click's writing or presentation that hotspot doesn't even think about JIT compiling something until it happens order of 10,000 times. He has a nice writeup on microbenchmarks in general and in relation to hotspot somewhere in the interweb.

18:39 Chousuke: mplayer used to often go into an infinite loop when I quit it, and the only way to tell it happened was to listen to the fan.

18:40 hiredman: heh

18:40 Chousuke: scgilardi: I've heard the 10k number before too.

18:40 hiredman: bah

18:40 audio from hulu.com isn't working now

18:52 technomancy: if you've got an object that implements Map, how do you make a clojure map out of it?

18:58 Chousuke: hmm.

18:59 technomancy: apart from reducing over the keyset

18:59 Chousuke: I think you need to do that.

18:59 Chouser: you can use 'get' on it just like a clojure map

18:59 technomancy: ok; I guess it's not too awkward

18:59 eevar: clojure map, Map instance, what's the difference?

19:00 Chousuke: eevar: a Map instance is not necessarily persistent :)

19:00 Chouser: clojure.lang.IPersistentMap vs java.util.Map

19:00 hiredman: ,(clojure.lang.IPersistentMap. {})

19:00 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for interface clojure.lang.IPersistentMap

19:00 Chousuke: hiredman: it's an interface

19:01 hiredman: ,(clojure.lang.APersistentMap. {})

19:01 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class clojure.lang.APersistentMap

19:01 Chousuke: ,(class {})

19:01 clojurebot: clojure.lang.PersistentArrayMap

19:01 hiredman: ,(clojure.lang.PersistentArrayMap. {})

19:01 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to [Ljava.lang.Object;

19:01 Chouser: if you want to do anything other than make a seq of it, or look up an item, you'll need to copy it into a clojure map

19:01 ,(supers {})

19:01 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class

19:01 Chousuke: the seq will be a weird one too :/

19:01 Chouser: ,(supers (class {}))

19:01 clojurebot: #{clojure.lang.IMeta clojure.lang.Obj clojure.lang.Counted java.lang.Runnable java.io.Serializable clojure.lang.AFn java.lang.Object java.util.concurrent.Callable clojure.lang.IPersistentMap clojure.lang.IFn clojure.lang.APersistentMap clojure.lang.IPersistentCollection clojure.lang.IObj clojure.lang.Associative java.lang.Iterable java.util.Map clojure.lang.Seqable}

19:01 Chousuke: it just contains a bunch of Entries :p

19:01 Chouser: but the destructure, so it's ok

19:02 Chousuke: ,(into {} (java.util.HashMap. {1 2 3 4}))

19:02 clojurebot: {3 4, 1 2}

19:02 Chouser: ,(java.util.HashMap {:a 1, :b 2})

19:02 clojurebot: java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn

19:02 Chousuke: cool.

19:02 Chouser: Chousuke: uh, right, what you said. :-)

19:02 technomancy: (apply hash-map (seq my-map))

19:02 much better than reducing with assoc

19:03 Chouser: into is roughly the same there.

19:03 (apply array-map my-map) may have slightly different results.

19:03 Chousuke: apply might be a bit faster

19:03 into uses reduce conj I think

19:03 technomancy: oh crap... but in this case my keys are all byte arrays, and I want strings. lousy.

19:04 Chousuke: hmm

19:04 Chouser: fear not! zipmap

19:04 technomancy: oh! I just read about that last week.

19:05 Chousuke: (apply hash-map (map (fn [k v] [(convert k) v]) mymap))

19:05 technomancy: that's probably better actually

19:06 Chousuke: oops. the parameter list has to be [[k v]]

19:06 Chouser: (zipmap (map convert (keys mymap)) (vals mymap)) ; why not?

19:09 technomancy: Chouser: oh! didn't realize I could call keys on mymap; thought that just worked on PersistentHashMaps

19:09 was thinking I'd have to convert it to a clj map, split it apart, and then reassemble it, but that's not true

19:09 yay interfaces!

19:45 hiredman: clojurebot: what do you think of scala?

19:45 clojurebot: excusez-moi

19:45 hiredman: clojurebot: have you ever tried scala?

19:45 clojurebot: Excuse me?

19:49 Raynes: I think the syntax hurt's my eyes considerably.

19:54 hiredman: clojurebot: what do you think of scala?

19:54 clojurebot: "you can usually accomplish a lot by laboriously enumerating type arguments everywhere." -- seen in #scala

20:12 gnuvince_: Has anyone tried the new 6u14 Sun JVM with escape analysis? Does it help with the performance of Clojure programs?

20:14 technomancy: gnuvince_: was going to, but I thought I'd better wait for approval from Oracle first.

20:15 * technomancy books a flight to Delphi

20:15 slashus2: hmm?

20:15 gnuvince_: technomancy: heh

20:15 It's not yet in Arch's repos, so I can't test it myself

20:15 (don't feel like installing by hand)

20:16 slashus2: I can go download the binaries on my Linux system.

20:22 gnuvince_: What would you like me to test?

20:25 gnuvince_: One guy on Reddit mentions a numerical test

20:25 Try something involving numbers

20:26 Not sure what's a numerical test that's long though

20:26 slashus2: (+ 1 2) seems to be a little slower in the new JVM.

20:26 clojurebot: 3

20:26 gnuvince_: Personally, I want to try it on my own Clojure project

20:27 But making a good test would involve downloading 100+ MB of files to analyse

20:27 slashus2: gnuvince_: Do you think that the upcoming chunked seqs are going to have a great impact on your project?

20:28 gnuvince_: I kind of doubt it

20:28 My issue doesn't seem to be the time required to process data, but the creationg of data structures in tight loops

20:28 slashus2: Scratch my last comment. I don't think that little addition thing is any different.

20:29 gnuvince_: Though I guess one of my main "loops" is a big reduce call

20:29 So, I guess I'll have to see

20:30 slashus2: When I launch clojure with -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC the jvm crashes

20:31 so much for the G1 garbage collector

20:31 gnuvince_: :)

20:35 slashus2: I get better times with the new vm with (dotimes [_ 10] (time (reduce + (range 1000000))))

20:36 250 ms compared to 284 ms

20:37 comparing with and without escape analysis

20:37 gnuvince_: ,(count (ns-publics 'clojure.core))

20:37 clojurebot: 459

20:38 slashus2: These micro-benchmarks don't say much.

20:49 gnuvince_: About the new chunked stuff, do I need t change something in my program or does it just happen when I svn up?

20:50 slashus2: I think it is going to be transparent for the most part.

20:51 gnuvince_: I just compiled your code clj-starcraft

20:51 gnuvince_: You'll need replay files now

20:51 Hang on

20:53 I made a tarball of 100 of them

20:54 Chouser: gnuvince_: the chunked stuff isn't all in yet

20:54 gnuvince_: Chouser: ok, but like I said earlier, I think I'll get a bigger speed improvement if I try to move some processing out of those tight loops

20:56 Hang on, I'm uploading the file...

21:08 slashus2: gnuvince_: large file?

21:08 gnuvince_: Not really, but my upload bandwidth sucks

21:08 http://senduit.com/008764

21:08 12 MB

21:09 (I upload at 20KB/s)

21:09 slashus2: okay done downloading it.

21:10 gnuvince_: try this command: time java -server -cp /path/to/clojure.jar:/path/to/clj-starcraft.jar clojure.main dump.clj *.rep

21:10 On my machine, it takes about 10 seconds for those 100 files. Java take 2 seconds for the same 100 files and 12 seconds for 1050 files.

21:11 (Clojure takes 70+ seconds for the 1050 files)

21:13 any difference between the two JVMs?

21:13 slashus2: I am setting everything up.

21:14 gnuvince_: ok

21:14 Sorry, didn't mean to rush you :)

21:15 slashus2: I am getting a strange error... java.lang.NoSuchMethodError: clojure.lang.Util.equal(Ljava/lang/Object;Ljava/lang/Object;)Z

21:18 gnuvince_: Seems to be line 18

21:18 in parse.clj

21:19 gnuvince_: the (if (= len 1)?

21:22 slashus2: That is where it ends.

21:24 gnuvince_: oh

21:24 I didn't see the part about the error

21:24 sorry

21:24 hmmm

21:24 that's weird...

21:24 slashus2: Is it giving you an error?

21:25 gnuvince_: no

21:25 slashus2: Let me try this on my other computer.

21:26 Chouser: that sounds most like a classpath or clojure.jar issue

21:26 Chousuke: did you try recompiling?

21:26 slashus2: Yep

21:29 gnuvince_: Are you using the latest svn revision?

21:29 gnuvince_: yep

21:30 slashus2: I recompiled clojure clojure-contrib and then compiled clj-starcraft with those

21:32 gnuvince_: Mercurial doesn't report any changes I haven't pushed

21:34 slashus2: hmm

21:34 Now it works.

21:34 I erased it and repulled it with mercurial.

21:34 Seems to work now.

21:35 gnuvince_: ok

21:36 slashus2: it took around 21.5 seconds with the built in java in ubuntu 9.04

21:37 gnuvince_: gcj?

21:38 slashus2: openjdk 6b14

21:38 With the binaries from sun it was about the same with 21.3. Now I will apply the special flags to the vm

21:39 With escape analysis turned on it did 18.5

21:39 I will run it again to confirm the improvement

21:40 Second run gave 20.1.

21:40 Oh well

21:40 Chousuke: server or client VM?

21:40 slashus2: server

21:41 There seems to be a slight improvement with the escape analysis turned on.

21:42 With the G1GC turned on, I get 15.2 seconds

21:42 gnuvince_: I really should refactor the whole thing and try and move a bunch of stuff out of those loops

21:43 slashus2: So the G1 helps in this case quite a bit.

21:43 I wish I could test it with both, but the jvm crashes when I turn on both escape analysis and the G1GC

21:46 gnuvince_: ok

21:46 Thanks for the tests

21:47 slashus2: With EscapeAnalysis I get: 20-23 seconds With the G1GC turned on I get: 14-15 seconds

21:48 gnuvince_: Cool

21:48 Still, I better clean up my code

21:48 slashus2: I don't think escape analysis deviated much from the run without it.

21:48 gnuvince_: I wonder if visualvm could help...

21:49 slashus2: I have that installed, but I don't really know how to use it.

21:52 hiredman: http://blog.juma.me.uk/2008/12/17/objects-with-no-allocation-overhead/ <-- review of the ea

22:09 slashus2: gnuvince_: On line 104, you might want to change = to == to get a little performance boost?

22:10 I am getting 13.5 after changing that and coercing cmd-size and (.position buf) to int to make (+ (int cmd-size) (int (.position buf)))

22:15 gnuvince_: I seem to recall trying that and not seeing a difference (though I had expected one)

22:15 let me try...

22:17 10.97s for = and 11.32 for ==

22:18 slashus2: gnuvince_: Did you try the second change?

22:18 Yeah the equals thing didn't make the difference.

22:18 It was the second change that made the difference.

22:19 gnuvince_: 12.1s

22:19 it seems to go in the opposite direction on my machine...

22:19 slashus2: I am using the G1GC

22:20 gnuvince_: I don't have it

22:20 slashus2: Maybe try both the changes together?

22:20 gnuvince_: But you see, this function is the one I should be changing

22:20 I should not be creating those maps in that loop

22:21 slashus2: How are you going to go about changing it?

22:21 gnuvince_: I'm not sure yet

22:22 Rewrite it in Haskell maybe? :)

22:22 slashus2: I think this "improvement" that I am seeing with those changes is due to the normal errors of the times.

22:23 gnuvince_: That would be a neat experiment. Do you like haskell?

22:24 I have been reading real world haskell, but I hit a wall when I started reading about the type system.

22:25 gnuvince_: I do like Haskell

22:25 And the more I use their type system, the more I believe that static typing is probably the way to go

22:26 slashus2: How long did it take you to become comfortable with their type system?

22:26 gnuvince_: To give you an idea, I tried Haskell 4 times before I finally "clicked" with it

22:26 And that was AFTER I had clicked with OCaml!

22:26 slashus2: I haven't even looked at OCaml

22:26 gnuvince_: Haskell is definitely *not* a simple language

22:26 But it's worth it in my opinion

22:27 slashus2: Good performance?

22:27 gnuvince_: As for the type system, I'd say I still sometimes struggle with it

22:27 Haskell or OCaml?

22:27 (mind you, both have pretty good performance, although getting good performance is easier with OCaml)

Logging service provided by n01se.net