2009-05-29
| 00:29 | djpowell | hoeck: yeah that is easier |
| 00:30 | djpowell | 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 |
| 00:31 | djpowell | I'm seeing that my function proxies the call to the clojure logging function via RestFn.invoke. What is RestFn? |
| 00:37 | opqdonut | how do I read a string into an int? |
| 00:40 | djpowell | ,(Integer/parseInt "123") |
| 00:40 | clojurebot | 123 |
| 00:41 | djpowell | is there a better way that isn't restricted to Java ints? |
| 00:42 | djpowell | hmm, this is better: |
| 00:42 | djpowell | ,(read-string "123") |
| 00:42 | clojurebot | 123 |
| 00:42 | talios | ,(Integer/valueOf "5") |
| 00:42 | clojurebot | 5 |
| 00:47 | djpowell | ,(num (read-string "1234")) ; if you want to fail if it isn't a num, but still support the whole numeric tower |
| 00:47 | clojurebot | 1234 |
| 03:20 | alinp | hi |
| 03:20 | Chouser | hi |
| 03:20 | alinp | can anyone please tell me what is wrong with this code: http://pastie.org/493850 |
| 03:20 | alinp | ? |
| 03:20 | alinp | I get NPE ... and I don't really get it |
| 03:23 | alinp | I don't really get it ... means that I don't got an idea where it comes from |
| 03:23 | Chousuke | alinp: the nil is the initial value of the agent, and you're trying to add 1 to it. |
| 03:24 | Chousuke | or maybe not... hm |
| 03:24 | alinp | yey |
| 03:24 | alinp | thanks Chousuke |
| 03:24 | alinp | this was it ... |
| 03:24 | alinp | at least for me |
| 03:24 | alinp | but .. shouldn't be the case |
| 03:25 | Chousuke | (doc send) |
| 03: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)" |
| 03:25 | alinp | because I'm not adding to agent value |
| 03:26 | jdz | you are |
| 03:26 | Chousuke | the agent's state goes in as the first parameter to f |
| 03:26 | alinp | (defn second-test [coll] |
| 03:26 | alinp | (map (fn [x] (send (agent nil) (fn [_] (+ x 1)))) coll)) |
| 03:26 | alinp | (def x (second-test (list 1 2 3))) |
| 03:26 | alinp | and it works |
| 03:27 | alinp | also the agent is having nil value |
| 03:27 | Chousuke | yeah, because now you're ignoring the agent's value :) |
| 03:27 | Chousuke | instead, you're using x |
| 03:27 | alinp | oh, crap |
| 03:27 | jdz | why are you creating agents with nil state? |
| 03:27 | alinp | the agent's value is going instead of _ |
| 03:27 | Chousuke | alinp: ? |
| 03:27 | alinp | don't know, because I don't have an initial state of it ?! |
| 03:28 | Chousuke | alinp: _ is just an "I don't care" marker |
| 03:28 | alinp | yes, this is what I said .. . |
| 03:28 | Chousuke | it still gets assigned the value though. which is the agent's state in this case. |
| 03:28 | alinp | I didn't saw where the agent's value was placed |
| 03:28 | Chousuke | it's not easy to see from that, I agree :/ |
| 03:29 | Chousuke | in your test-map call it kinda looks like y would be the list values, but they're not. |
| 03:29 | Chousuke | instead, you're completely ignoring the list :) |
| 03:30 | alinp | I see |
| 03:30 | alinp | thanks |
| 03:30 | alinp | so .. there is a solution for that ? |
| 03:30 | alinp | or the solution will be not to use nil ? |
| 03:30 | Chousuke | is there a problem to solve? what do you actually want to do? |
| 03:31 | Chousuke | have an agent and add a listful of value to it? |
| 03:31 | Chousuke | values* |
| 03:31 | alinp | no, have a list and apply a function to all elements that is spawning a thread for each element |
| 03:31 | Chousuke | ah |
| 03:32 | alinp | and I don't want to do it (thread spawning) outside of this function |
| 03:32 | alinp | 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 |
| 03:32 | Chousuke | maybe you should use futures. |
| 03:33 | alinp | well, but can't be done this way ? :) |
| 03:33 | Chousuke | hmm |
| 03:33 | alinp | to be honest, I'm just playing |
| 03:33 | Chousuke | sure it can, but... gmm |
| 03:33 | alinp | it's not something for production or so .. |
| 03:33 | Chousuke | but if you want to use agents: (map (fn [item] (send-off (agent initvalue) f item)) coll) |
| 03:34 | rhickey | ,(doc pmap) |
| 03: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." |
| 03:34 | Chousuke | or that :D |
| 03:35 | alinp | ha |
| 03:35 | alinp | yes, is what I want to do :) |
| 03:35 | alinp | ok, thank you |
| 03:35 | alinp | I'll see about that |
| 03:36 | Chouser | alinp: and then you can look at the definition of pmap and learn how its done. :-) |
| 03:36 | alinp | yes, sure, this is what I have in mind :D |
| 03:36 | alinp | *I had |
| 03:43 | alinp | Chousuke: |
| 03:43 | alinp | ,(map (fn [x] (send (agent nil) (fn [_] (+ x 1)))) coll)) |
| 03:43 | clojurebot | java.lang.Exception: Unable to resolve symbol: coll in this context |
| 03:44 | alinp | ,(map (fn [x] (send (agent nil) (fn [_] (+ x 1)))) (list 1 2 3))) |
| 03:44 | clojurebot | (#<Agent@15ec870: nil> #<Agent@1b95de0: nil> #<Agent@c22530: nil>) |
| 03:44 | alinp | hmmmm |
| 03:44 | alinp | wtf ? |
| 03:45 | alinp | ,(map (fn [item] (send-off (agent 0) f item)) (list 1 2 3)) |
| 03:45 | clojurebot | java.lang.Exception: Unable to resolve symbol: f in this context |
| 03:45 | alinp | (def f (fn [p] (+ p 1))) |
| 03:45 | alinp | (map (fn [item] (send-off (agent 0) f item)) (list 1 2 3)) |
| 03:45 | alinp | java.lang.IllegalArgumentException: Wrong number of args passed to: user$f |
| 03:46 | alinp | (map (fn [item] (send-off (agent 0) (f item))) (list 1 2 3)) |
| 03:46 | alinp | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 03:47 | alinp | (map (fn [item] (send-off (agent 0) (fn [_] (f item)))) (list 1 2 3)) |
| 03:47 | alinp | it seems that I need to do something like this |
| 03:49 | hoeck | alinp: your function f has to take the agent state as the first arg |
| 03:50 | hoeck | alinp: it should be (defn f [p item] (+ p item)) |
| 03:50 | Chousuke | yes |
| 03:50 | Chousuke | functions sent to agents must always take the agent as the first parameter |
| 03:50 | Chousuke | the state of the agent that is |
| 03:50 | alinp | oh, I see |
| 03:50 | Chousuke | just send + to it :) |
| 03:51 | Chousuke | ,(map #(send-off (agent 5) + %) [1 2 3]) |
| 03:51 | clojurebot | (#<Agent@7704dd: 6> #<Agent@1e05ef2: 5> #<Agent@1799932: 5>) |
| 03:52 | Chousuke | hmm |
| 03:52 | Chousuke | that's not what I expected :D |
| 03:52 | alinp | ha |
| 03:52 | alinp | :) |
| 03:52 | Chousuke | might be the asynchrony |
| 03:52 | Chousuke | the rest of the agents didn't complete the action before the map thing printed them |
| 03:53 | Chousuke | ,(map #(send (agent 5) + %) [1 2 3]) |
| 03:53 | clojurebot | (#<Agent@8eb8bf: 5> #<Agent@31f94: 5> #<Agent@10e58a3: 5>) |
| 03:53 | Chousuke | hmm. |
| 03:53 | alinp | (defn my-map [f coll] |
| 03:53 | alinp | (map |
| 03:53 | alinp | (fn [item] (send-off (agent nil) (fn [_] (f item)))) |
| 03:53 | alinp | coll) |
| 03:53 | alinp | ) |
| 03:53 | alinp | this is what I made ... |
| 03:53 | alinp | and it seems it working ;) |
| 03:54 | Chousuke | yeah, that would work. |
| 03:54 | Chousuke | and send and send-off are both asynchronous |
| 03:54 | Chousuke | :p |
| 03:54 | alinp | yep |
| 03:54 | Chousuke | also, putting the closing paren on its own line is not very lispy :) |
| 03:54 | alinp | the thing is that I was taking always the value of agent |
| 03:55 | Chousuke | you should learn the Real Way! |
| 03:55 | alinp | and not the value of each item |
| 03:55 | Chousuke | you'll ~never see code like that anyway. |
| 03:55 | alinp | you're talking about what piece of code ? (mine, of course, but which) |
| 03:55 | Chousuke | so you need to get used to the closing parens not being on separated |
| 03:55 | Chousuke | the ) at the end |
| 03:55 | Chousuke | it should be after coll) |
| 03:56 | Chousuke | and also the end paren for defn should be after those |
| 03:56 | Chousuke | lisppaste8: url |
| 03:56 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 03:56 | alinp | I see, well .. I saw plenty of clojure code this way ... |
| 03:56 | Chousuke | where? :/ |
| 03:57 | alinp | I don't remember right now ... but I'll be sure to show you some when I see it ;) |
| 03:58 | alinp | "and also the end paren for defn should be after those" |
| 03:58 | alinp | what do you mean ? |
| 03:58 | alinp | (defn my-map [f coll] |
| 03:58 | alinp | (map |
| 03:58 | alinp | (fn [item] (send-off (agent nil) (fn [_] (f item)))) |
| 03:58 | alinp | coll)) |
| 03:58 | alinp | this is what you mean ? |
| 03:59 | lisppaste8 | chousuke pasted "coding style" at http://paste.lisp.org/display/81021 |
| 04:00 | alinp | yep, cool, thanks |
| 04:00 | Chousuke | when writing lisp, don't match parentheses manually; let the editor do it for you |
| 04:00 | alinp | well, yes... but |
| 04:00 | alinp | anyway, is better than haskell |
| 04:01 | alinp | I hate the indentation stuff |
| 04:01 | alinp | tabs over spaces ... etc |
| 04:01 | Chousuke | lisp has no forced indentation but there are of course conventions you should follow. |
| 04:02 | Chousuke | for example, one indent is generally two spaces |
| 04:02 | alinp | yes, this is how my vim is configured for clj |
| 04:05 | Chousuke | grouping the end parens has the effect that lisp code usually has quite a distinct "shape" |
| 04:05 | Chousuke | and if that shape looks weird, you may need a rewrite ;) |
| 04:53 | durka42 | github's clojure highlighter has a few bugs >:o |
| 04:55 | hiredman | so does the php highlighter |
| 04:58 | gnuvince | I blame Ruby |
| 05:15 | alinp | it is possible in clojure to create an initial list with n agents ? |
| 05:15 | alinp | or .. n elements |
| 05:15 | alinp | it doesn't matter if are agents or other type |
| 05:16 | cmvkk | like this? |
| 05:16 | cmvkk | ,(repeat 5 0) |
| 05:16 | clojurebot | (0 0 0 0 0) |
| 05:16 | alinp | make-array is used for classes |
| 05:16 | alinp | yes, like this :) |
| 05:16 | alinp | thanks cmvkk |
| 05:17 | {newbie} | Hi I have a list of stuff I want to pass to a var arg function? |
| 05:17 | {newbie} | how do i destruct the list into multiple values? |
| 05:17 | Chouser | {newbie}: apply |
| 05:18 | alinp | {newbie}: map |
| 05:18 | {newbie} | thanks ^^ |
| 05:18 | alinp | hmmm, apply will be better, Chouser is right |
| 06:00 | hiredman | ,(map agent (repeate 5 nil)) |
| 06:00 | clojurebot | java.lang.Exception: Unable to resolve symbol: repeate in this context |
| 06:00 | hiredman | ,(map agent (repeat 5 nil)) |
| 06:00 | clojurebot | (#<Agent@866463: nil> #<Agent@128b564: nil> #<Agent@19ce804: nil> #<Agent@446cc5: nil> #<Agent@4127cf: nil>) |
| 06:25 | hiredman | Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated |
| 06:25 | hiredman | Nice |
| 06:47 | rhickey | ooh: http://java.sun.com/javase/6/webnotes/6u14.html |
| 06:47 | rhickey | 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. |
| 06:48 | Chousuke | cool |
| 06:49 | stuartsierra | So that eliminates the object-allocation penalty? |
| 06:50 | Chousuke | I wish I weren't on OS X so I could try and see what kind of effect that has :) |
| 06:50 | rhickey | Chousuke: me too :( |
| 06:50 | rhickey | stuartsierra: in some cases - it will be interesting to see which ones |
| 06:58 | durka42 | i like -XX:+UnlockExperimentalVMOptions |
| 06:58 | durka42 | clojure has *leveled up*! clojure has unlocked new VM features! |
| 06:59 | Chousuke | heh |
| 06:59 | Chousuke | hmm, there's a recent java developer preview update on ADC |
| 06:59 | Chousuke | let's see which version it is ;P |
| 07:00 | Chousuke | damn, 1.6.0_13 |
| 07:00 | Chousuke | no fair |
| 07:01 | Chousuke | still, probably worth upgrading |
| 07:02 | rhickey | how's everyone doing with chunked seqs? |
| 07:03 | Chouser | haven't noticed any problems |
| 07:04 | Chouser | could lazilypersistentvectors and arraymaps each provide one big chunk? |
| 07: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 |
| 07:07 | Chouser | does a chunk stay the same size through the whole chain? |
| 07:07 | Chouser | I hadn't thought about that, but I guess it must. |
| 07:07 | rhickey | not necesarily |
| 07:08 | rhickey | you can have heterogeneous seqs, with some chunks some not |
| 07:08 | Chouser | but most intermediate funcs (map, filter, etc.) won't do extra work to break up or coalesce chunks? |
| 07:09 | rhickey | Chouser: no, ideally they should copy the incoming chunk size, filter and its ilk being the exception |
| 07:10 | rhickey | chunked-seq, or whatever we call it, will actually drop the chunk if it is empty - (chunked-seq [] foo) => foo |
| 07:11 | rhickey | sorry, meant chunked-cons above |
| 07:11 | rhickey | (chunked-cons [] foo) => foo |
| 07:12 | rhickey | Chouser: ah, now I see, by through the chain you mean chain of calls, not chain of seqs |
| 07:12 | clojurebot | Who?? |
| 07:13 | Chouser | yes, sorry, the call chain |
| 07:13 | rhickey | then yes, will be same size, thus whole-coll-as-chunk = bad |
| 07:13 | Chouser | got it |
| 07:14 | rhickey | that's why LazilyPersistentVector.ChunkedSeq is the way it is |
| 07:14 | Chouser | so... lpv and arraymap could provide artificially small chunks of themselves at whatever the "ideal" size is. |
| 07:14 | Chouser | oh. |
| 07:14 | Chouser | 32. ok. |
| 07:15 | Chouser | that was my next question |
| 07:15 | rhickey | there is still an issue for multi-seq map regarding chunk alignment |
| 07:16 | rhickey | ditto any other multi-seq consumer, like zipmap or interleave |
| 07:16 | Chouser | mmm, sure. |
| 07:16 | rhickey | the simplest default is to do chunks only when aligned |
| 07:16 | rhickey | thus 32 |
| 07:17 | rhickey | but not guaranteed, since e.g. hashmap chunks are sparse |
| 07:17 | Chouser | any sense of how small chunks can be and still be worth the overhead (if any)? 2 items? 4? |
| 07: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 |
| 07: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. |
| 07:19 | rhickey | Chouser: the trick is remembering the half-chunk you didn't yet consume |
| 07:19 | Chouser | yeah. all them. :-) |
| 07:19 | rhickey | I thought about it and got a headache |
| 07:22 | rhickey | but, one of the reasons this is in trunk is I welcome contributions towards getting it fully done. I foresee the need for: |
| 07:22 | rhickey | chunked arrayseqs |
| 07:22 | rhickey | chunked hashmap seqs, plus chunked keys and vals seqs |
| 07:22 | rhickey | multi-arg map |
| 07:22 | rhickey | vectors of primitives |
| 07:23 | rhickey | chunked versions of arithmetic ops, both chunk/chunk and chunk/scalar |
| 07:23 | rhickey | chunked-map which takes a fn expecting chunks |
| 07:23 | rhickey | chunked-pmap |
| 07:24 | rhickey | integration of chunking logic in the core seq fns where it makes sense - I'll do map/filter/reduce as examples |
| 07:24 | Chouser | I don't understand chunked arithmetic |
| 07:24 | rhickey | (+ chunk-of-ints chunk-of-ints) => chunk-of-ints |
| 07:26 | Chouser | can't do that with seqs now, can you? |
| 07:26 | rhickey | (chunked-map + int-vector1 int-vector2) |
| 07:26 | rhickey | the perf of this would be as good as loops with primitives |
| 07:28 | Chouser | map* as pasted yesterday doesn't tell f it's got a chunk. is there some other api detail I'm missing? |
| 07: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 |
| 07:29 | Chouser | sounds absolutely gorgeous, but I'm not seeing how all the pieces fit together yet. |
| 07: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 |
| 07:30 | rhickey | + would become such a fn |
| 07:30 | rhickey | (map-chunked + int-vec1 int-vec2), would pass the first chunk from each to + |
| 07:31 | rhickey | + would be overloaded for chunks |
| 07:31 | rhickey | so instead of boxing each int, we 'box' entire chunks in int-vectors |
| 07:31 | stuartsierra | Just got my "Programming Clojure" -- pretty nifty. |
| 07:31 | Chouser | oh, so map-chunked is different from map* and map |
| 07:31 | Chouser | (yes, I understand map* is going away) |
| 07:31 | rhickey | Chouser: yes, map-chunked passes chunks o f |
| 07:31 | rhickey | to f |
| 07:32 | Chouser | got it. |
| 07:32 | Chouser | and what are these vectors of primitives you slipped in there? |
| 07: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 |
| 07:33 | rhickey | (int-vec 1 2 3 4) |
| 07:34 | rhickey | hm, int-vector I guess |
| 07:34 | Chouser | sounds like a lot more boilerplate Java code. |
| 07:34 | Chouser | but great to use! :-) |
| 07:34 | rhickey | when seq'ed, a primitive vector's chunks will be chunks of primitives |
| 07:35 | rsynnott | stuartsierra: oh, they released it? |
| 07:35 | rhickey | math ops will detect such chunks and do primitive/primitive op, boxing occurring once per chunk |
| 07: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. |
| 07:36 | stuhood | so the main benefit is speed then? |
| 07:37 | stuhood | imo, the speed isn't worth it unless the chunking can be done transparently |
| 07:37 | stuartsierra | rsynnott: yes |
| 07:37 | Chouser | stuhood: it will be |
| 07:38 | stuhood | ah, i misunderstood map-chunked |
| 07:38 | asbjxrn | Even non-transparent speed is worth it if you need it. |
| 07: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. |
| 07: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 |
| 07:39 | rhickey | this is best-of-both-worlds, IMO |
| 07: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) |
| 07:40 | rhickey | also the increased granularity means pmap might makes sense in more cases, since the per-step work unit is bigger |
| 07: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 | stuhood | 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 | Chouser | 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 | 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 | stuhood | 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 | rhickey | Mathematica has a similar notion |
| 12:56 | rhickey | 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 | {newbie} | it works outside a functioin |
| 13:02 | {newbie} | 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 | {newbie} | [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 | {newbie} | it is not highlighted in my editor |
| 13:04 | {newbie} | 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 | Chousuke | 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 | slashus2 | 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 | Chouser | 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 | {newbie} | 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 | Chousuke | 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 | Chousuke | 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 | Chousuke | (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 | Chouser | oh, ok. |
| 13:22 | rhickey | A struct map will retain its base keys in order. |
| 13:22 | rhickey | http://clojure.org/data_structures |
| 13:23 | {newbie} | nice thanks! |
| 13:23 | Chouser | wow, that's coming up fast. |
| 13:23 | Chousuke | :/ |
| 13:24 | Chousuke | 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 | stuartsierra | 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 | cemerick | (testing "foo" (= blah (foo))) evals the equality, but doesn't assert it. |
| 13:33 | stuartsierra | That's correct. |
| 13:33 | stuartsierra | '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 | Chouser | 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 | rhickey | 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 | 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 | alinp | http://pastie.org/494198 |
| 13:41 | alinp | 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 | alinp | ? |
| 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 | cmvkk | it's just a list. |
| 13:43 | dnolen | python interactive mode sucks, it can't even handle updating imported libs. |
| 13:43 | dnolen | 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 | alinp | and I modified the code a little bit |
| 13:44 | alinp | and it seems that I did wrong |
| 13:44 | alinp | so, it's about that |
| 13:44 | alinp | thanks |
| 13:44 | alinp | 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 | alinp | in fact is my fault that I did copied the code without knowing exactly what it does |
| 13:46 | alinp | yes, I don't need that |
| 13:46 | alinp | for sure |
| 13:46 | alinp | 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 | alinp | well ... I can create a list of agents .... (def ring (repeat ring-size (agent nil))) |
| 13:47 | alinp | 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 | alinp | 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 | alinp | well , I didn't said that it's a lazy seq |
| 13:48 | Chousuke | yeah. |
| 13:48 | Chousuke | (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 | alinp | oh |
| 13:48 | alinp | crap |
| 13:48 | alinp | 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 | alinp | 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 | alinp | 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 | 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 | ataggart | 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 | Chousuke | 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 | {newbie} | yet |
| 13:54 | technomancy | wise |
| 13:54 | Chousuke | most of the time you don't need them, anyway |
| 13:55 | Chousuke | 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 | cemerick | FWIW, of course. I'd have a lot more weight if I had put together a shiny demo. :-/ |
| 13:56 | technomancy | everyone understands telnet, and there's less overhead to explain than HTML-generation |
| 14:02 | technomancy | with mire I had a multiplayer text adventure working in < 60 LOC. that could make a good demo. |
| 14:03 | Chousuke | heh |
| 14:04 | Chousuke | 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 | technomancy | don't know about JavaOne, but conference wifi is usually sketchy |
| 14:05 | technomancy | but yes, that would be pretty cool. |
| 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 | durka42 | 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 | durka42 | 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 | durka42 | 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 | emacsen | 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 | durka42 | 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 | durka42 | 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 | Chousuke | 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 | durka42 | ,(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 | Chousuke | ,(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 | durka42 | ,(.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 | durka42 | ,(.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 | Chousuke | 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 | emacsen | 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 | Chousuke | how do you call it? :/ |
| 14:31 | emacsen | I'm getting my more CL knolwedgeable friend to come and explain it |
| 14:31 | emacsen | 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 | Chousuke | 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 | 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 | slashus2 | 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 | Chousuke | 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 | Chousuke | 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 | Chousuke | they should use the doc index on the site! |
| 14:40 | Chousuke | :P |
| 14:40 | Chousuke | 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 | emacsen | even if that's with a separate tool ala pydoc |
| 14:41 | Chousuke | hmm |
| 14:41 | Chousuke | well, that shouldn't be too difficult |
| 14:41 | Chousuke | 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 | technomancy | 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 | 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 | emacsen | BTW, since I heard about them in the interview, are these "ports" official? |
| 14:52 | emacsen | clojurescript and the C# one? |
| 14:52 | technomancy | what does "official" mean? |
| 14:52 | emacsen | Well, good question |
| 14:52 | emacsen | What is a Clojure? :) |
| 14:52 | emacsen | is there a test suite? |
| 14:52 | technomancy | Clojure is still implementation-defined. |
| 14:53 | technomancy | the test suite is ... not a high priority. |
| 14:53 | technomancy | 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 | emacsen | 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 | emacsen | 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 | Chousuke | and I don't think the ports are in any way official |
| 15:05 | Chousuke | 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 | Chousuke | 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 | technomancy | 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 | Chousuke | 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 | Chousuke | the latest java for OS X is... u13 |
| 15:10 | hiredman | heh |
| 15:10 | hiredman | 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 | ataggart | 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 | ataggart | 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 | slashus2 | 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 | hiredman | 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 | ataggart | which is probably what's happening anyway |
| 15:30 | ataggart | larger numbers as a result of mathematical operations. typically you'd cast to int before such ops |
| 15:30 | ataggart | 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 | jlb | 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 | jlb | ataggart: same exception |
| 15:43 | ataggart | hm |
| 15:43 | ataggart | 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 | rich_holygoat | 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 | ataggart | my first EJB project was in 2000 |
| 15:49 | ataggart | 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 | ataggart | not in the classpath would be a different excpetion, so ya not that |
| 15:53 | ataggart | 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 | hiredman | classpath is handled by java |
| 15:54 | hiredman | 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 | hiredman | add-classpath is your problem |
| 15:58 | hiredman | don't ever use it and expect it to work |
| 15:58 | ataggart | classpath being not mutable during runtime |
| 15:59 | ataggart | 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 | jlb | I'll try to figure out what is going on w/ CLASSPATH then |
| 16:00 | ataggart | (= (getClassLoader (class #{})) (getClassLoader (class foo))) |
| 16:00 | ataggart | try running that |
| 16:00 | ataggart | 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 | Chouser_ | 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 | j-dot | 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 | Chousuke | I guess it needs parameters |
| 16:09 | ataggart | no public constructor |
| 16:10 | Chousuke | ah, heh |
| 16:10 | ataggart | erm, well |
| 16:10 | ataggart | 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 | Chousuke | but at least it isn't like the iTerm source code :P |
| 16:11 | ataggart | ok, no arg constructor is protected |
| 16:11 | ataggart | 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 | j-dot | 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 | jlb | (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 | Chousuke | 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 | ataggart | 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 | ataggart | so -cp ./:clojure.jar:jline.jar:ejb.jar:other-libs.jar |
| 16:19 | ataggart | 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 | technomancy | 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 | duck1123 | if I try to kill it from the *SLIME Connections* buffer, it kills the server |
| 17:13 | duck1123 | 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 | duck1123 | 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 | technomancy | 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 | technomancy | 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 | hiredman | D: |
| 17:35 | technomancy | hiredman: your slashes are backwards. |
| 17:35 | technomancy | 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 | arohner | :-) |
| 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 | hiredman | apparently the 32bit jre for windows does not come with hotspot |
| 17:55 | Chousuke | huh |
| 17:56 | Chousuke | 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 | Chousuke | anyway, perhaps you need the java SDK |
| 17:57 | Chousuke | or some enterprisey version :P |
| 17:58 | technomancy | hotspot comes in client and server varieties |
| 17:58 | Chousuke | hmm, yeah |
| 17:58 | Chousuke | "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 | Chousuke | certainly helps |
| 18:07 | Chousuke | 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 | replaca | 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 | arohner | I dropped CL *because* it was a lisp-2 |
| 18:26 | replaca | (let [f (fn [x y] ...)] ...) is bliss |
| 18:26 | replaca | 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 | replaca | 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 | hiredman | 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 | hiredman | 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 | hiredman | I just messing with Queues |
| 18:32 | Chousuke | can't do them myself either :( |
| 18:32 | Chousuke | would require installing Linux and probably the JVM manually too |
| 18:32 | Chousuke | :P |
| 18:32 | hiredman | erg |
| 18:33 | hiredman | slowed down |
| 18:33 | hiredman | 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 | Chousuke | right. |
| 18:36 | Chousuke | probably not a good benchmark of escape analysis. |
| 18:36 | Chousuke | 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 | hiredman | 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 | hiredman | 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 | Chouser | ,(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 | technomancy | much better than reducing with assoc |
| 19:03 | Chouser | into is roughly the same there. |
| 19:03 | Chouser | (apply array-map my-map) may have slightly different results. |
| 19:03 | Chousuke | apply might be a bit faster |
| 19:03 | Chousuke | 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 | technomancy | 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 | technomancy | 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 | slashus2 | hmm? |
| 20:15 | gnuvince_ | technomancy: heh |
| 20:15 | gnuvince_ | It's not yet in Arch's repos, so I can't test it myself |
| 20:15 | gnuvince_ | (don't feel like installing by hand) |
| 20:16 | slashus2 | I can go download the binaries on my Linux system. |
| 20:22 | slashus2 | gnuvince_: What would you like me to test? |
| 20:25 | gnuvince_ | One guy on Reddit mentions a numerical test |
| 20:25 | gnuvince_ | Try something involving numbers |
| 20:26 | gnuvince_ | 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 | gnuvince_ | 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 | gnuvince_ | 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 | gnuvince_ | 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 | slashus2 | 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 | slashus2 | 250 ms compared to 284 ms |
| 20:37 | slashus2 | 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 | slashus2 | gnuvince_: I just compiled your code clj-starcraft |
| 20:51 | gnuvince_ | You'll need replay files now |
| 20:51 | gnuvince_ | Hang on |
| 20:53 | gnuvince_ | 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 | gnuvince_ | 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 | gnuvince_ | http://senduit.com/008764 |
| 21:08 | gnuvince_ | 12 MB |
| 21:09 | gnuvince_ | (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 | gnuvince_ | 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 | gnuvince_ | (Clojure takes 70+ seconds for the 1050 files) |
| 21:13 | gnuvince_ | any difference between the two JVMs? |
| 21:13 | slashus2 | I am setting everything up. |
| 21:14 | gnuvince_ | ok |
| 21:14 | gnuvince_ | 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 | slashus2 | gnuvince_: Seems to be line 18 |
| 21:18 | slashus2 | in parse.clj |
| 21:19 | gnuvince_ | the (if (= len 1)? |
| 21:22 | slashus2 | That is where it ends. |
| 21:24 | gnuvince_ | oh |
| 21:24 | gnuvince_ | I didn't see the part about the error |
| 21:24 | gnuvince_ | sorry |
| 21:24 | gnuvince_ | hmmm |
| 21:24 | gnuvince_ | 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 | slashus2 | 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 | slashus2 | Now it works. |
| 21:34 | slashus2 | I erased it and repulled it with mercurial. |
| 21:34 | slashus2 | 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 | slashus2 | 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 | slashus2 | With escape analysis turned on it did 18.5 |
| 21:39 | slashus2 | I will run it again to confirm the improvement |
| 21:40 | slashus2 | Second run gave 20.1. |
| 21:40 | slashus2 | Oh well |
| 21:40 | Chousuke | server or client VM? |
| 21:40 | slashus2 | server |
| 21:41 | slashus2 | There seems to be a slight improvement with the escape analysis turned on. |
| 21:42 | slashus2 | 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 | slashus2 | 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 | gnuvince_ | 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 | gnuvince_ | 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 | slashus2 | 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 | gnuvince_ | let me try... |
| 22:17 | gnuvince_ | 10.97s for = and 11.32 for == |
| 22:18 | slashus2 | gnuvince_: Did you try the second change? |
| 22:18 | slashus2 | Yeah the equals thing didn't make the difference. |
| 22:18 | slashus2 | It was the second change that made the difference. |
| 22:19 | gnuvince_ | 12.1s |
| 22:19 | gnuvince_ | 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 | gnuvince_ | 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 | gnuvince_ | 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 | slashus2 | gnuvince_: That would be a neat experiment. Do you like haskell? |
| 22:24 | slashus2 | 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 | gnuvince_ | 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 | gnuvince_ | 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 | gnuvince_ | 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 | gnuvince_ | Haskell or OCaml? |
| 22:27 | gnuvince_ | (mind you, both have pretty good performance, although getting good performance is easier with OCaml) |