#clojure log - Jun 03 2009

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

1:16 sunwukong: is there a function in core/contrib for #(filter identity %) ?

1:17 (that is, removing every nil/false element from a coll)

1:59 replaca: sunwukong: not that I can think of off hand

1:59 sunwukong: ok, thanks

7:41 cemerick: whew, the rhickey interview from qcon is done in a very unpleasant format, IMO

7:42 arbscht: got a link?

8:00 cemerick: arbscht: http://www.infoq.com/interviews/hickey-clojure

8:00 arbscht: thanks

8:00 cemerick: it's sort of an interview, but the interviewer is sitting in the audience, which strikes me as odd

8:18 gnuvince: cemerick: that interview is not really good IMO because the interviewer sticks mostly to his notes and is generally boring

8:18 cemerick: yeah, that too :-)

8:20 gnuvince: Interviewers should be more like Simon Peyton-Jones

8:24 cemerick: I don't think I've seen him interview anyone.

8:26 gnuvince: Me neither, I mean that the interviewer should be enthused and engaging instead of sitting his butt on a chair and just going through a list of questions.

8:44 cemerick: the treatment of the last map in an apply form as a seq of args can lead to some very hard-to-diagnose bugs

8:45 I guess I'm supposed to know what I'm doing with all this rope ;-)

8:46 Chouser: heh

8:50 eliantor: hi

8:51 Chouser: eliantor: hello

8:51 cemerick: Chouser: what's your take on the UI stuff from javaone? I was pretty bummed about the consistent soft-pedaling of swing.

8:52 Chouser: cemerick: didn't pick up on that. you're referring to the big javafx push in the keynote?

8:53 eliantor: i'm trying to do something like this: (map + [[1 2 3] [1 2 3]]) --> [2 4 6]

8:53 cemerick: I saw a bunch of tweets about sun people saying they're "still planning on *supporting* swing", jwebpane maybe being released alongside jdk7, but not included in the jre, etc.

8:54 twitter rumors are probably not the best thing to go by, but it's what I've got right now :-)

8:54 eliantor: i mean how can i inline a list to provide it to map?

8:54 Chouser: ,(apply map + [[1 2 3] [1 2 3]])

8:54 clojurebot: (2 4 6)

8:54 eliantor: thanks

8:54 :)

8:55 cemerick: also:

8:55 ,(map + [1 2 3] [1 2 3])

8:55 clojurebot: (2 4 6)

8:55 cemerick: if you have distinct collections

8:55 Chouser: cemerick: hmph. and is javafx their replacement for it, or am I confused.

8:55 cemerick: ech, join the club.

8:56 they don't have much of any story around javafx widgets that would be the analog of those available in swing, so I don't see how they can expect people to make the jump.

8:57 Maybe all UIs are supposed to be done in photoshop or their "JavaFX Designer" vaporware :-P

8:57 Chouser: you know, the canvas 2d api isn't that complicated -- if you've got a canvas-based ui toolkit you like, what about something that proovides not a full browser stack, but just a canvas compatible api?

8:57 do you have a canvas-based ui toolkit you like? :-)

8:58 cemerick: canvas-based UI toolkit? Like dojo, or whatever?

8:58 Chouser: cemerick: I dunno, I thought that's why you wanted jwebpane

9:00 cemerick: I want jwebpane for a variety of reasons. Most of all, I don't want to be dragging a "legacy" toolkit around everywhere, and there's going to be light and heat around canvas for the next decade at least.

9:08 is there a "deep" map merge somewhere? (deep-merge {:a #{1 2}} {:a #{3 4}}) => {:a #{1 2 3 4}}

9:08 ah, deep-merge-with, perhaps :-)

9:59 drewr: Reminder: Clojure Search http://www.google.com/coop/cse?cx=004621955734675372103:0oxuogeollc

10:07 lisppaste8: cgray pasted "gen-class problem" at http://paste.lisp.org/display/81280

10:08 chillitom: i think I've just realised a massive problem with my UniqueBlockingQueue.. because all methods are synchronized a call to take() can never return if the queue is empty

10:08 cgray: so I'm having trouble figuring out why the class that I'm generating isn't getting loaded properly...

10:09 chillitom: damn conncurency is difficult!

10:09 Chouser: chillitom: yeah, that's actually a feature. :-)

10:09 .take not returning is a feature, I mean, not that concurrency is complex. :-/

10:10 cgray: java.lang.IllegalStateException: Cannot create AdaptiveSignalSystemControler for class name:

10:10 playground.cgray.adaptivecontroler

10:10 any ideas?

10:11 Chouser: cgray: That's not all in one file, is it?

10:11 cgray: Chouser: no, after add-classpath is in a different file

10:12 Chouser: hey, you know what though -- if all you're doing is implementing an interface, I *highly* recommend proxy over gen-class, even if you intend to compile to .class files.

10:12 cgray: I don't think that works in my case. I have to give the name of the class to an xml file

10:13 Chouser: bah. ok.

10:13 well, the first thing I'd try is getting rid of the add-classpath

10:14 set your classpath on the command line with -cp and then try compiling

10:14 cgray: what do you mean?

10:15 Chouser: java -cp clojure.jar:src clojure.main

10:15 then you can bind *compile-path* to "src" and try compiling.

10:15 add-classpath is unreliable.

10:16 cgray: ok, good to know

10:19 hmm, from the command line I get a ClassNotFoundException on the interface that I am trying to implement

10:19 and it's in a jar that's on the classpath

10:20 no, never mind

10:20 the jar wasn't on the classpath :)

10:21 Chouser: :-)

10:24 cgray: ok, so it compiles. how would I test if it can actually be loaded?

10:26 Chouser: (new playground.cgray.adaptivecontroler)

10:26 rys: http://www.infoq.com/news/2009/06/g1-free-or looks like Sun changed the wording on G1 in the latest update to 6

10:26 Chouser: (.givenSignalGroupIsGreen (new playground.cgray.adaptivecontroler))

10:28 dnolen: rys: good

10:28 cgray: the first one worked, the second one didn't

10:28 Chouser: cgray: odd. What kind of error did you get?

10:28 cgray: No matching field found

10:30 Chouser: oh, it wants an arg. my bad.

10:30 (.givenSignalGroupIsGreen (new playground.cgray.adaptivecontroler) nil)

10:30 cgray: thanks, I should have caught that :)

10:33 Chouser: cgray: so add-classpath was the only thing you had to change?

10:33 cgray: so it works at the repl, but when the larger application tries to call it, it still barfs... at least I know that problem isn't with clojure though...

10:41 Chouser: I missed your question. I think it was working, I just wasn't testing it properly.

10:41 Chouser: oh, even with add-classpath it was working?

10:42 cgray: I think

10:42 Chouser: ok

10:56 cemerick: is there a deep macroexpand anywhere yet?

10:56 gnuvince: Not built-in

10:56 I don't know about clojure-contrib

10:57 cemerick: well, clojure.contrib.macros doesn't have one, which I presume would be where it'd be.

10:57 cgrand1: konrad has put a macroexpand-all in contrib

10:58 cemerick: ah, it's in walk

10:59 cgrand1: or mexpand-all in macro-utils

11:02 walk/macroexpand-all seems to not care about locals nor special symbols

11:03 stuartsierra: cgrand1: yes, that's true, but it should still work

11:09 Chouser: Why doesn't this work: (defn #^bytes foo [])

11:09 dnolen: isn't that a primitive type?

11:16 cemerick: hrm, type-hinting issues is this week's theme

11:17 Chouser: dnolen: it means an array of primitive bytes when used in other type-hinting contexts.

11:17 dnolen: primitive arrays aren't Objects

11:17 functions can only return Objects

11:18 this is what the whole boxing issue on primitive types is all about

11:18 Chouser: ,(make-array Byte/TYPE 10)

11:18 clojurebot: #<byte[] [B@8bb8b2>

11:18 Chouser: what's that?

11:18 dnolen: the repl printing out a primitve, this probably uses reflection I'm assuming.

11:19 could be wrong of course, but this was the take away when rhickey explained it.

11:19 Chouser: no, I think you're incorrect. make-array is a function, and it's returning a thing

11:19 ,(instance? Object (make-array Byte/TYPE 10))

11:19 clojurebot: true

11:19 dnolen: but that might be boxed right?

11:20 Chousuke: ,(class (make-array Byte/TYPE 10))

11:20 clojurebot: [B

11:20 cemerick: Chouser: maybe defn doesn't play well with the primitive hints? {:tag (Class/forName "[b")} ?

11:20 Chousuke: :P

11:20 Chouser: I think a primitive can't be returned by a clojure function, but an *array* of primitives is fine.

11:20 Chousuke: hmm

11:21 the bash prompt git branch addition is nice

11:21 now I no longer need to type "git branch" to know where I am.

11:22 cemerick: speaking of git, my quick experiment to keep patches on top of a git-svn clone of clojure's svn didn't go well. Apparently, one cannot push git-svn state to a git remote...?

11:22 Chousuke: I think it's possible somehow manually though.

11:22 danlarkin: I think that (instance? Object (make-array Byte/TYPE 10)) comes back as true because passing the array to instance? boxes it? since it's a function boundary?

11:22 dnolen: Chouser gotcha, dunno then.

11:23 ,(instance? Object (ints (make-array Integer/TYPE 10)))

11:23 clojurebot: true

11:23 Chouser: danlarkin: make-array is clojure function -- the thing that it returns has to obey the same rules as any args would.

11:23 stuartsierra: You can do (defn #^"[B" my-function ...)

11:24 dnolen: ,(instance? Object (int 1))

11:24 clojurebot: true

11:25 dnolen: no way that is true

11:25 Chousuke: ,(class (int 1))

11:25 clojurebot: java.lang.Integer

11:25 danlarkin: it's the function boundary

11:25 dnolen: yes

11:25 Chouser: stuartsierra: ouch. But yes, that works fine. Thanks.

11:25 * Chouser looks forward to explaining this to the C++ guys.

11:26 * danlarkin looks forward to it being changed :)

11:26 Chouser: int is not a plain function

11:26 dnolen: ,(instance? Object 1)

11:26 clojurebot: true

11:26 Chouser: 1 is a boxed object

11:26 dnolen: than how can you know that something is primitive?

11:26 Chouser: do it in a big loop and see if it's slow?

11:27 dnolen: haha

11:27 Chouser: :-)

11:27 stuartsierra: dnolen: arguments to Clojure fns are always boxed.

11:27 Chousuke: ~def instance?)

11:27 clojurebot: Excuse me?

11:27 Chousuke: oops

11:27 ~def instance?

11:27 dnolen: stuartsierra: yeah.

11:28 Chousuke: ,(.isInstance (int 1) Object)

11:28 clojurebot: java.lang.IllegalArgumentException: No matching method found: isInstance for class java.lang.Integer

11:28 Chouser: it's hard because primitives are boxed almost without you even touching them.

11:28 Chousuke: ,(.isInstance Object (int 1))

11:28 clojurebot: true

11:29 Chouser: boxed!

11:29 Chousuke: evil

11:29 danlarkin: we're experiencing the quantum phenomenon, where observing a thing inherently changes it!

11:29 stuartsierra: You can only get primitives in a loop.

11:30 aravind: hi

11:30 Chouser: the real problem is that you want to be able to see what the compiler concludes about stuff. This is after read, after macro-expand, but before bytecode-generation.

11:30 The compiler's got an AST that describes all it's conclusions, but it's hard to get to and opaque.

11:30 clojure-in-clojure will fix that, and allow questions like this to be answered well.

11:32 ,(clojure.lang.Compiler/analyze clojure.lang.Compiler$C/EXPRESSION '(int 5))

11:32 clojurebot: #<StaticMethodExpr clojure.lang.Compiler$StaticMethodExpr@138009b>

11:32 dnolen: so has anyone tested, are chunked-seqs as fast as loop/recur?

11:32 Chousuke: aren't they potentially faster :/

11:33 dnolen: that would be great

11:33 aravind: I have a for loop that that acts on a list of two items generates a sequence of two lists, something like ((1 2 3) (4 5 6)). however, I want it to generate a map with two entries, one for each of the entries in the for seq.

11:33 Chousuke: unless you loop over chunks I guess.

11:33 Chouser: I thought rhickey claimed he had tests showing they were faster in some cases.

11:33 aravind: I have been trying all kinds of combinations but I finally gave up..

11:33 Chouser: aravind: I don't understand -- what should the map look like?

11:33 {1 4, 2 5, 3 6} ?

11:34 aravind: okay, the for acts on (:a :b) and generate ((1 2 3) (4 5 6)), I want the final map to be {:a (1 2 3) :b (4 5 6)}

11:34 Chousuke: ,(map list [[1 2] [3 4] [5 6]]); you mean you have something like this?

11:34 clojurebot: (([1 2]) ([3 4]) ([5 6]))

11:34 Chousuke: er, whoops

11:34 ,(map list [1 2] [3 4] [5 6]); you mean you have something like this?

11:34 clojurebot: ((1 3 5) (2 4 6))

11:35 Chouser: ,(zipmap [:a :b] '((1 2 3) (4 5 6)))

11:35 clojurebot: {:b (4 5 6), :a (1 2 3)}

11:36 aravind: hmm..

11:36 ,(zipmap (:a :b) '(((1 2 3) (4 5 6))))

11:36 clojurebot: {}

11:37 dnolen: aravind: (:a :b) is not a quoted list

11:37 aravind: also why are you using lists instead of vectors, lists are rarely the right choice.

11:37 ,(zipmap [:a :b] [[1 2 3] [4 5 6]])

11:37 clojurebot: {:b [4 5 6], :a [1 2 3]}

11:37 aravind: dnolen: all that stuff is autogenerate from java iterators (or some sort of java arrays).

11:38 dnolen: I have to somehow conver them to be sequences to use them in clojure, and (seq java-form), only generates lists?

11:38 dnolen: (vec (make-array Integer/TYPE 10))

11:38 ,(vec (make-array Integer/TYPE 10))

11:38 clojurebot: [0 0 0 0 0 0 0 0 0 0]

11:38 dnolen: you can convert java arrays into vectors

11:39 Chousuke: aravind: seq doesn't generate lists; it generates seqs :)

11:39 dnolen: ,(vec (seq '(1 2 3 4)))

11:39 clojurebot: [1 2 3 4]

11:40 aravind: okay, but doesn't it feel like an aweful lot of convertions.. just to be able to use the results?

11:40 Chousuke: if you have seqs there's no need to put them in a vector usually, but sometimes it helps

11:40 but if you're typing out literal sequences, '(1 2 4 5 232 43232) is rather unclojurey

11:40 vectors are more idiomatic in that case.

11:41 aravind: dammit, I swear I looked through zipmap, but it didn't strike me as something I could use for this.

11:41 dnolen: aravind: heh Clojure is like that. most of the things you could think of for operating on sequences is already there.

11:42 aravind: so something like (zipmap (vector generating-array) final-generated-array) should work for my case.

11:43 dnolen: yeah, for a while there, I was actually calling the java iterator and stepping through next.. before I read about seq :(

11:43 Chouser: ,(let [compiler-type #(let [e (clojure.lang.Compiler/analyze clojure.lang.Compiler$C/EXPRESSION %)] (.getJavaClass e))] (compiler-type '(int 5)))

11:43 clojurebot: int

11:43 Chouser: ,(let [compiler-type #(let [e (clojure.lang.Compiler/analyze clojure.lang.Compiler$C/EXPRESSION %)] (.getJavaClass e))] (compiler-type '(+ 5 10.5))))

11:43 clojurebot: java.lang.Number

11:43 dnolen: heh cool

11:43 Chouser: ,(let [compiler-type #(let [e (clojure.lang.Compiler/analyze clojure.lang.Compiler$C/EXPRESSION %)] (.getJavaClass e))] (compiler-type '(+ (int 5) (float 10.5)))))

11:43 clojurebot: float

11:43 dnolen: c.c.compiler-helper?

11:46 aravind: thanks guys, that works beautifully. Sometimes I should just give up sooner and beg for help

11:46 dnolen: perfect macro for checking what the compiler sees for a given expression.

11:48 Chouser: I'm afraid it might add to confusion...

11:59 Chousuke: Chouser: I just wonder when clojure-in-clojure is actually going to materialise.

12:00 Chouser: Chousuke: it's not next on Rich's list, I think, but not last either.

12:00 Chousuke: I guess rhickey is going to have to implement the instance thing first

12:00 Chouser: he said that, but I don't understand why yet.

12:01 compiler-type's a bad name for that thing. What should I call it?

12:01 ,(let [compiler-type #(let [e (clojure.lang.Compiler/analyze clojure.lang.Compiler$C/EXPRESSION %)] (when (.hasJavaClass e) {:class (.getJavaClass e) :primitive? (.isPrimitive (.getJavaClass e))}))] (compiler-type '(+ (int 4) 5)))

12:01 clojurebot: {:class java.lang.Number, :primitive? false}

12:02 Chousuke: compiler-info

12:02 hmm

12:02 stuartsierra: compiler-tag

12:02 Chousuke: you could expand the function to return as much compiler knowledge as you can and return a map.

12:03 Chouser: well.. that's what clojure-in-clojure does. ;-)

12:03 Chousuke: heh

12:03 Chouser: I guess not really.

12:03 Chousuke: your code as it is looks a bit scary :P

12:04 Chouser: in general, or in this case?

12:04 :-D

12:04 Chousuke: I mean in the clj-clojure code you have on github

12:04 Chouser: oh. yeah. ugly.

12:04 Chousuke: 50 lines is a lot for a lisp function.

12:05 Chouser: what's there is largely the result of a (incomplete) learning process on my part. It probably ought to be scrapped and written from scratch.

12:06 but then Compiler.java is over 5000 which is (I hope) a lot for a .java file.

12:07 Chousuke: fairly large, yes :P

12:09 cemerick: an optional string arg should be added to time that is appended to the elapsed time printlns.

12:11 Chouser: "expr-info"?

12:11 cemerick: yeah, something along those lines

12:14 Chousuke: people are too fond of abbreviating things IMO ;P

12:14 Chouser: Chousuke: "expression-information"?

12:15 Chousuke: I think just expression-info would be fine :)

12:15 cemerick: current-expression-timing-description gets my vote

12:15 * cemerick sheathes the over-the-top snark

12:17 Chousuke: I just think the programmer's fingers don't matter as much as the burden on the reader :P

12:18 stuartsierra: speak for yourself -- I have carpal tunnel and tendinitis. :)

12:18 cemerick: There's certainly a balance to be had. Some of the names in CL are abominations, for instance.

12:18 Chousuke: ... and most IDEs and editors have keyword completion anyway

12:19 cemerick: oh-no -- not the "IDEs will save us from ourselves" bit

12:19 That's the #1 counterargument to "java/C# is too verbose"

12:19 cp2: personally i like the cl names

12:19 Chousuke: cemerick: in this case, I think "expr-info" would be too abbreviated simply because it's difficult to pronounce if you read it aloud.

12:19 arohner: replaca?

12:20 Chousuke: I still have no idea what that does.

12:20 Chouser: "ehk-SPRINFO"

12:20 dnolen: sexpr-info

12:20 Chousuke: looks like a misspelling of replica :/

12:20 Chouser: sex-pr-info

12:21 cemerick: cp2: least-negative-normalized-double-float?

12:22 arohner: Chousuke: it's surprisingly hard to google for the definition of replaca

12:22 duck1123: does anyone know why the tests for clojure.contrib.sql are showing up in the documentation on the wiki?

12:22 Chousuke: arohner: heh

12:22 arohner: but there are two functions, replace car, and replace cdr

12:22 replacA, replacD

12:22 Chousuke: so why couldn't they just keep the r

12:22 cp2: cemerick: lol

12:22 Chousuke: that would have made it a LOT better.

12:23 arohner: or even replace-car

12:23 Chousuke: ; I totaled my Toyota ;(

12:23 arohner: though early lisps may have had a limit on the fn name length

12:24 cemerick: yeah, it was 7 chars in the really early days

12:24 arohner: though I'm amazed car and cdr stuck around as long as they did

12:32 does anyone else find themselves writing (interleave (keys map) (vals map)) a lot?

12:33 stuartsierra: only in macros

12:33 arohner: several core fns want a flat seq of key value pairs, but (seq map) returns ([k v] [k v]). I find myself needing to fix that often

12:34 Chousuke: ,(apply concat {1 2 3 4})

12:34 clojurebot: (1 2 3 4)

12:34 stuartsierra: I wrote a flatten-map function, I think it's in contrib somewhere.

12:35 Chousuke: that's better.

12:35 arohner: that is a better solution. Though I'm kind of wondering why there are fns that take lists of key value pairs rather than a map

12:36 Chousuke: they're usually map-constructing functions I suppose

12:36 stuartsierra: Before array-map, maps were unordered, too.

12:38 cemerick: stuartsierra: perhaps test-is/testing should emit a separator between different context names? I see it puts a space there now, but something more to indicate the separation between levels would be good. first context / second context / third ... etc.

12:39 stuartsierra: cemerick: I was copying RSpec, where concatenating the contexts is supposed to yield a complete sentence.

12:40 cemerick: oh, I see

12:40 heh, that seems really unlikely to work out, except in contrived examples

12:40 stuartsierra: That's why I don't like it.

12:41 cemerick: "when only the demo slides matter..."

12:41 arohner: that's never stopped ruby before

12:43 cemerick: Chousuke: I just noticed your msg from earlier -- are you OK?

12:44 Chousuke: cemerick: you mean the toyota one? fortunately that was a joke on replace-car. :)

12:44 cemerick: HA!

12:55 replaca: arohner: despite my nick, the CL funcs are rplaca, rplacd, iirc

12:56 http://www.lispworks.com/documentation/HyperSpec/Body/f_rplaca.htm#rplaca

14:19 hiredman: When he was pointed out that Clojure is already doing what he wants, he said "Well, I don't like the square brackets" :-(

14:19 * hiredman dies laughing

14:20 danlarkin: who said that?

14:21 hiredman: http://www.artima.com/weblogs/viewpost.jsp?thread=259505 The EuroLisp Symposium and the Future of Common Lisp

14:21 Scott McKay

14:22 danlarkin: This seems accurate, "The impression I got is that he would only accept as new Common Lisp a language designed by himself..."

14:24 hiredman: "one sends his proposal to the CDR site and nothing happens"

14:27 replaca: If Clojure's as successful as that language about which people say, "I don't like the fact that whitespace is syntactically significant," I'll be happy. :-)

14:27 the rest of the world can dislike our parens and square brackets

14:27 hiredman: http://infoworld.com/d/developer-world/java-get-more-modular-jdk-7-upgrade-919 "Class path is dead,"

14:29 Chouser: huh

14:34 Chousuke: nice and vague: "The modularity aspect gives us a taste of how perhaps we're getting to a point where we can start to think about how we might end up with one Java" :P

14:36 wwmorgan: is there a function in core or contrib that takes a directory and returns all files under it, traversing the directory structure?

14:37 slashus2: wwmorgan: Tried file-seq?

14:37 wwmorgan: slashus2: that's it. Thanks

14:38 mrsolo: is there better way to do this? (defn unique [a] (sort (into () (set a))))

14:38 minus the sort part

14:38 Chouser: 'a' is any collection?

14:38 mrsolo: ya

14:39 or just list if that matters

14:39 Chousuke: sorted-set?

14:39 or did that exist

14:39 danlarkin: Yess, down the classpath!

14:39 mrsolo: basically i wants to remote duplciates '(1 2 2) -> '(1 2) etc

14:39 Chouser: set is probably faster than sorted-set

14:39 Chousuke: right

14:39 Chouser: but he's going to sort anyway

14:40 Chouser: (seq (set a)) should do it

14:40 mrsolo: sort isn't necessary..but i found that the elements order aren't guanarntee after transformation...

14:41 Chousuke: right.

14:41 is the original seq containing the duplicates sorted?

14:41 mrsolo: it contains duplicated, not sorted

14:42 but i couldn't figure out a way to collaps item in place

14:42 so.. will just enforce sort order

14:42 Chousuke: are the duplicates always adjacent?

14:42 mrsolo: no

14:42 Chouser: can you just use a set in your algorithms instead of a list?

14:42 Chousuke: okay, so putting stuff in a set is probably better.

14:42 mrsolo: hmm

14:43 may be let me check

14:44 hiredman: ~def clojure.set/union

14:45 a lot of the operations in clojure.set call seq or use functions that call seq :(

14:47 mrsolo: hmm probably not.. i uses lots of concat mapcat filter etc.. the change isn't worth it..

14:47 Chouser: (expression-info '(+ (int 5) (float 10))) ==> {:class float, :primitive? true}

14:48 hiredman: ooo

14:49 cemerick: Chouser, Dark Lord of the Cons

14:50 danlarkin: neat

14:51 Chouser: (expression-info '(/ 5 2)) ==> {:class java.lang.Number, :primitive? false}

14:51 (expression-info '(/ (int 5) (int 2))) ==> nil

14:52 (expression-info '(/ (float 5) (int 2))) ==> {:class float, :primitive? true}

15:30 cemerick: hrm, trying to print refs that have metadata fails reliably

15:30 oh, only those that have :type metadata

15:31 Chouser: that's because the printer dispatches on :type

15:31 it's a feature!

15:32 hiredman: I feel a disturbance

15:32 cemerick: Chouser: right, but there's a :default dispatch for print-method. The problem is that the fn for :default tries to dissoc the :type metadata out of the object being printed (which might also be a feature? ;-) )

15:33 hiredman: as if millions of abstractions had just become concrete

15:38 danlarkin: the fu is strong with you

15:40 stuartsierra: Anyone know a decent Java SSH library?

15:41 hiredman: apache may have one

15:42 looks like not

15:42 stuartsierra: nope

15:42 StartsWithK: jsch

15:42 http://www.jcraft.com/jsch/

15:42 stuartsierra: I've tried JSch and j2ssh, both are clumsy and poorly documented.

15:42 StartsWithK: http://www.ganymed.ethz.ch/ssh2/

15:43 if all fails try this one

15:43 i haven't used it

15:43 stuartsierra: No longer maintained, by the original author or Trilead.

15:43 StartsWithK: but looks complete

15:44 trilead died like 2 weeks ago

15:44 hiredman: http://mina.apache.org/sshd/

15:44 :/

15:44 StartsWithK: they deleted public repo and everything :/

15:44 hiredman: http://mina.apache.org/sshd/embedding-sshd-in-5-minutes.html <-- thats kinda cool

15:44 StartsWithK: jna+native ssh libs?

15:44 that will be my last option too

15:45 stuartsierra: No JNA, I'd rather call the command-line client.

15:45 MINA looks interesting.

15:45 hiredman: mina is the framework the twitter guys used for their scala thing

15:46 #java doesn't seem to be fond of it, but #java is also home to an author of a competing framework

15:46 StartsWithK: grizzly? :)

15:47 hiredman: something affiliated with jboss

15:48 stuartsierra: What's the jboss one?

15:48 hiredman: xnio maybe?

15:49 the issue with the framework whosename I can't remember is it is annotation driven, which is bad for clojure integration

15:49 stuartsierra: xnio looks like a sockets library

15:49 * stuartsierra is building MINA

15:50 StartsWithK: mina has ssh client? or server only?

15:50 stuartsierra: that's what I'm trying to figure out

15:50 StartsWithK: ssh/sftp?

15:51 hiredman: Apache SSHD is a 100% pure java library to support the SSH protocols on both the client and server side.

15:51 This library is based on Apache MINA, a scalable and high performance asynchronous IO library.

15:51 SSHD does not really aim at being a replacement for the SSH client or SSH server from Unix operating systems, but rather provides support for Java based applications requiring SSH support.

15:53 stuartsierra: It does include a SshClient class, though.

15:54 StartsWithK: and in the frist example it looks dead simple to use it (at the top of .java file)

15:58 * stuartsierra is digging through source code.

16:07 stuartsierra: "NoClassDefFoundError: org/apache/mina/core/future/IoFutureListener"

16:07 * stuartsierra sighs

16:13 StartsWithK: it looks like it requires main mina distribution to work, http://svn.apache.org/repos/asf/mina/trunk/core/src/main/java/org/apache/mina/core/future/IoFuture.java

16:29 arohner: is there a way to use -> if the result should go into an arg other than the first?

16:29 hiredman: arohner: yes, but it isn't pretty

16:30 ,(-> 1 (#(/ 3 %)))

16:30 clojurebot: 3

16:30 arohner: hmm

16:30 thanks

16:30 cemerick: template should be able to make that better eventually...

16:30 (if not already)

16:30 arohner: template?

16:31 cemerick: clojure.contrib.template

16:31 I've only used it in the context of test-is, but controlling placement of values in -> seems like a natural next step

16:32 what hiredman showed is clearly easier than what you'd have to do right now using template, but a -> variant that explicitly used it shouldn't be too difficult.

16:34 arohner: thanks

17:06 bhurt: Is there a retry for Clojure transactions, like Haskell's retry? Basically, it just aborts the current transaction and waits until one of the STM ref cells you accessed has been written, and then retries the transaction.

17:08 hiredman: sounds icky

17:08 bhurt: Ugly to implement, granted, but really useful.

17:09 hiredman: for what purpose?

17:10 bhurt: So I have a ref cell holding a map. If the element I'm looking for isn't in the map (and some other conditions hold), another thread is going to add the element RSN. A retry in this case would be exactly what I want to do.

17:11 Chouser: I just wrote await-iref, which you could do before entering your transaction.

17:11 stuartsierra: Reading a ref doesn't require a transaction.

17:11 hiredman: bhurt: you could just, you know, loop

17:11 bhurt: I don't want to busy wait.

17:12 Chouser: I haven't gotten rhickey's attention yet to see if the goals of await-iref are inherently flawed. :-)

17:12 hiredman: I think I'd use a blockingqueu

17:13 Chouser: http://paste.lisp.org/display/81237#2 -- await-iref (tested)

17:13 bhurt: so that's not a busy loop, but I'm not sure it's a good idea either.

17:13 hiredman: thread B does a blocking .take from the queue and thread A, when it updates the map, pushes some token into the queue

17:14 Chouser: There are plenty of existing concurrency mechanisms that might suffice: Semaphore, BlockingQueue, etc.

17:14 bhurt: A blocking queue might work...

17:14 A Semaphore would work as well.

17:15 Chouser: in my case, most of the time nobody cares when I'm updating the ref -- seems a shame to create/update a Semaphore every time.

17:16 So if I want to block on it, I use await-iref (which uses add-watch and a Semaphore) to block until some condition is met.

17:17 bhurt: I only create the semaphore when I'm inserting the element.

17:17 hiredman: :/

17:18 bhurt: This isn't that performance sensitive.

17:20 replaca: Chouser: I *like* that! A good use case for watchers.

17:21 Chouser: replaca: thanks, but like I said I'm a little worried I'm just unaware of some more correct alternative.

17:22 Or I guess more that this would be seen as an abuse of iref's or wathes or seomthing.

17:22 replaca: Chouser: you never know until you ask. Watchers are still marked *experimental*

17:22 but I'm using them in the object explorer thing I'm presenting tonight

17:23 Chouser: ha!

17:23 oh, watchers

17:23 yes, good.

17:23 something like watchers will be around. I think what's "experimental" is the specific API which has already been adjusted a couple times.

17:24 replaca: I drive the UI off a set of refs so you can update it interactively or programattically

17:24 and the various parts of the UI just watch the parts they're interested in

17:24 (basically like cells)

17:24 Chouser: yes, very good.

17:25 AWizzArd: ~ seen kotarak

17:25 clojurebot: kotarak was last seen quiting IRC, 8606 minutes ago

17:25 AWizzArd: ,(/ 8606.0 60)

17:25 clojurebot: 143.43333333333334

17:25 AWizzArd: ,(/ *1 24)

17:25 clojurebot: java.lang.IllegalStateException: Var clojure.core/*1 is unbound.

17:26 Chousuke: clojurebot has awful attention span :)

17:35 mrsolo: what is ~ in front of variable in defmacro for?

17:36 Chousuke: unquote

17:36 ,(let [foo 5] `(foo ~foo))

17:36 clojurebot: (sandbox/foo 5)

17:36 hiredman: ,(let [a 1] `(n ~a d))

17:36 clojurebot: (sandbox/n 1 sandbox/d)

17:36 mrsolo: thanks

18:40 gnuvince_: Is anybody getting these reflection warnings in the svn version?

18:40 Reflection warning, /home/vince/prog/clojure/clj-starcraft/dump.clj:3 - reference to field getClass can't be resolved.

18:40 Reflection warning, /home/vince/prog/clojure/clj-starcraft/dump.clj:3 - reference to field getClassLoader can't be resolved.

18:42 slashus2: gnuvince: yes

18:45 durka42: what else should I compile to get c.c.fnmap working? ant -Dclojure.jar=../clojure.jar didn't do it (java.lang.ClassNotFoundException: clojure.contrib.fnmap.PersistentFnMap)

18:46 gnuvince_: Wel..

18:47 Arch updated the JDK to 6u14

18:47 slashus2: gnuvince: I don't know.

18:47 gnuvince_: No change in my Starcraft program

18:47 :(

18:47 slashus2: gnuvince_: Did you activate the G1GC?

18:47 gnuvince_: It's not on by default?

18:47 slashus2: no

18:47 durka42: no you need some scary arguments

18:47 slashus2: -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

18:48 gnuvince_: (and regardless, I don't think this would make the difference I'm looking for)

18:48 slashus2: Try and see if that makes any difference at all.

18:48 durka42: PS, they rewrote ("clarified") the thing about G1GC requiring a support contract

18:48 now it just says it may eat your pets when turned on

18:49 Chousuke: gnuvince_: you said you had some performance problems with that starcraft thingy?

18:50 gnuvince_: Chousuke: not so much "problems" as "I'm annoyed that it's not more within Java's range"

18:50 slashus2: slower with G1GC

18:50 slashus2: nooooo

18:51 Chousuke: gnuvince_: where does most of the time go, though? :/

18:51 slashus2: Run it over and over again to make sure there were no anomalies.

18:51 gnuvince_: Chousuke: hang on, I'll run a few profile runs

18:52 slashus2: gnuvince_: Have you played around with visualvm?

18:52 gnuvince_: slashus2: not yet

18:53 Though I imagine the numbers won't be much different from -Xrunhprof

18:53 slashus2: no

18:53 It will just be prettier.

18:53 Chousuke: gnuvince_: I have the feeling that boxing things might be hurting performance

18:54 it's something that's fairly difficult to detect and avoid :/

18:54 gnuvince_: Chousuke: the most costly calls change from profile run to profile run

18:55 But it's between java.nio.Buffer.position and clojure.lang.Cons.first

18:55 java.lang.reflect.Array.setInt also takes a sizeable percentage

18:56 Chousuke: hmm

19:00 so what clojure function is calling these?

19:00 gnuvince_: Split between parsing the actual binary data and converting it to something "sensible" to the domain

19:02 Chousuke: if you want to play around with it, the code is on BitBucket and I can pack you up a bunch of data files to test

19:03 Chousuke: I might.

19:03 gnuvince_: Although my guess is that to attain Java-like performance, I'm going to need to radically change my approach

19:05 Chousuke: if you have a link to the data files, give me that and I'll download them for later use. I'm going to go to sleep soon but I can poke around tomorrow.

19:08 gnuvince_: Chousuke: uploading now

19:09 Chousuke: oh damn, I need to install hg

19:15 gnuvince_: argh

19:16 * gnuvince_ hates his upload bandwidth limitation

19:18 Chousuke: hmm

19:19 in make-reader using aset-int looks suspicious

19:22 gnuvince_: using aset or aset-int changes nothing

19:23 Oh come on!

19:23 I'm uploading the file

19:23 Site has a problem with it

19:23 * gnuvince_ shakes his fist!

19:24 dreish: Drawing a blank. Isn't there something equivalent to (dorun (for ...))?

19:24 Chousuke: I would assume that it wants a primitive int as the value you're putting in it, but that looks like a boxed value in all cases :/

19:25 dreish: doseq?

19:25 dreish: Thanks. For some reason I was thinking that was the same as doall.

19:25 I blame the heat.

19:26 Chousuke: gnuvince_: plus that it has to do reflection I think because the return type of (mask-fn (getter buf)) is not known at compile time.

19:26 gnuvince_: Chousuke: looking at Clojure's code, all aset-* functions use the reflection framework

19:26 So I think I'm pretty screwed there.

19:26 I tried to cast pretty much everything in that code block without success

19:26 Chousuke: ~def aset-int

19:29 gnuvince_: have you tried using a plain old vector?

19:31 hm

19:31 gnuvince_: I used one in the very early stages, but switched to an array for some reason

19:32 god damn

19:33 I can't upload this stupid file to senduit or at work

19:33 *sigh*

19:33 Chousuke: gnuvince_: :/

19:33 gnuvince_: I'll try a friend's server

19:34 Chousuke: well, if you get some data available somewhere, ping me. I really have to go get some sleep now. I'll investigate more later.

19:35 gnuvince_: damn

19:35 it always stalls

19:36 I'm beginning to think I'M the problem

19:36 rhickey: replaca: ping

19:36 gnuvince_: ok

19:40 ataggart: is there a way to clear out whatever junk I've added to the namespace when working in a repl? (other than ^D)

19:41 replaca: rhickey: yeah

19:41 rhickey: replaca: all set? seems like a big crowd

19:41 replaca: yeah!

19:41 rhickey: I have a 10 minute talk prepped on chunked seqs

19:42 replaca: it's going to be cozy. Who knew you were so popular?!

19:42 rhickey: sorry all presentation slots filled.

19:42 (joking!)

19:42 rhickey: Also, I saw the latest IntelliJ plugin - awesome. Can we squeeze in a few minutes for Ilya to demo?

19:42 replaca: sure.

19:42 I'd love to see it

19:42 rhickey: should be great - I'm heading out soon

19:43 thanks for putting this together

19:43 replaca: cool, phil, amit and a couple of others are already here working on swamiji stuff

19:43 *swarmiji

19:43 rhickey: see you soon

19:43 replaca: np, it's fun

19:44 dreish: I made a repl that runs things in the background if they take longer than *repl-timeout* seconds.

19:44 replaca: i'll put you on last (to lead in to town hall) and ilya right before you

19:48 gnuvince_: are you guys both at JavaOne or something?

19:49 replaca: a bunch of us just live here

19:49 a few are here for javaOne and a couple of others (like technomancy) are in just for the meetup

19:49 gnuvince_: ok

19:53 tbatchelli: I work a block away from the meetup venue :)

19:53 replaca: tbatchelli: hope you don't get stuck in traffic! :-)

19:53 luckily, the Giants are out of town

19:54 tbatchelli: replaca: if you guys need any help I can come over right now (I am bored)

19:56 replaca: Feel free to come when you want, but we're pretty well set up.

20:07 ataggart: I guess quite a few of us work in soma

20:12 replaca: now live from the SF clojure meetup!

20:23 dysinger: <crickets>

20:26 tashafa: how would ai go about creating a byte array in clojure?

20:30 hiredman: ,(make-array Byte/TYPE 10)

20:30 clojurebot: #<byte[] [B@1926603>

20:31 hiredman: ,(into-array Byte/TYPE [1 2 3 4])

20:31 clojurebot: java.lang.IllegalArgumentException: argument type mismatch

20:31 hiredman: bah

20:31 ,(into-array Byte/TYPE (map byte [1 2 3 4]))

20:31 clojurebot: #<byte[] [B@1c65470>

20:35 tashafa: thanks hiredman!

20:36 (doc byte)

20:36 clojurebot: "([x]); Coerce to byte"

20:52 dreish: http://gist.github.com/123364

21:29 technomancy: is there a significant overhead to running with the JVM args that jdb needs?

21:30 -agentlib:jdwp=transport=dt_socket,address=8021,server=y,suspend=n

21:34 dysinger: there is overhead

21:34 I don't have any stats

21:34 stuhood: i assume it would have to instrument every class and method

21:42 technomancy: obviously you wouldn't do it in production, but I wonder if it's worth leaving on in development

21:42 just so you don't have to restart when you realize you need it.

21:44 replaca: i love it that you two are chatting while sitting right next to each other

21:45 dysinger: does jdp actually instrument byte code? I thought it just inspected things as it was running.

21:45 I don't know though

21:47 Yeah I don't think it would hurt anything to run it locally like that most of the time.

21:47 if no debugger is connected - it just wont debug

21:48 technomancy: cool; adding it to my .emacs then

21:49 dysinger: one thing is this though - you can't run two on the same port

21:49 so you could only have one slime sess

21:51 durka42: you could come up with some clever way to auto-generate the port

21:52 dysinger: but you need the port number to connect the debugger

21:52 so you'd have to go look if you weren't using the default port

21:52 =====

21:52 somebody ask him if they use emacs underneath !

22:10 technomancy: oh bummer; if you try to start a Clojure instance with a jdb port that's in use it just fails to launch Clojure itself rather than just leaving jdb out.

22:20 chessguy: is it correct to say "a symbol can refer to a var that is bound to a value"?

22:20 i would have expected to see "a symbol can refer to a var to which is bound a value"

22:21 sounds strange to me to talk about something getting bound to a value instead of the other way around

22:25 lisppaste8: ozzilee pasted "Nested Macro Definitions" at http://paste.lisp.org/display/81329

22:25 technomancy: btw, you can vote for Clojure to get uploaded to the official mvn repos here: http://jira.codehaus.org/browse/MAVENUPLOAD-2464

22:26 ozzilee: I'd like write a macro that only exists inside another macro, as above. defaction outside of defservice should be an error. Is there something better than codewalking?

22:27 chessguy: technomancy: what's mvn?

22:27 ezyang: chessguy: Maven

22:27 chessguy: which is...

22:27 technomancy: chessguy: lets you handle dependencies in an automated fashion

22:27 so you don't have to manually manage jar files etc.

22:27 dysinger: babble babble

22:27 stuhood: dysinger: hehe

22:28 ezyang: chessguy: If you use Debian, it's sort of like apt

22:28 chessguy: ah, ok. i don't, but i do get the analogy :)

22:28 technomancy: chessguy: it does a lot of other things, but that's the part that's relevant to clojure

22:29 * technomancy likes how we're getting a preview of the new "summer color refresh" of the Clojure logo. (at the SF meetup)

22:29 hiredman: technomancy: is there a video camera in the room?

22:29 chessguy: so...do values get bound to vars, or vars to values?

22:29 dysinger: voted ?

22:30 technomancy: hiredman: yes, and there have even been loose plans announced to upload them.

22:30 * technomancy glances at replaca

22:32 ezyang: How important is it for me to learn clojure macros?

22:32 I've touched TeX and C macros, and I'm really not relishing the prospect

22:32 technomancy: ezyang: learn macros last.

22:32 ezyang: Ok.

22:33 dreish: Seconded. They're nice, but everyone who dives into Lisp because of macros tries to use them for everything that they shouldn't be used for.

22:33 technomancy: ezyang: they're useful, but it's easy to get carried away if you're relatively inexperienced

22:34 dysinger: Y it's like saying "there is no line between your language and your application" - can make debugging hard

22:35 technomancy: I love how rich always deflects questions about internals that you shouldn't have to care about. =)

22:36 hiredman: :D

22:37 dysinger: but his whole presentation is about internals that we shouldn't have to care about !

22:37 (chunked seqs)

22:37 should be transparent

22:37 hiredman: dysinger: well that depends

22:37 technomancy: yeah, he mostly does that when people ask about locking/concurrency details

22:37 because they're way more complicated than chunking

22:38 hiredman: I can imagine chunked seqs will be useful for library writting

22:38 (well the details of)

22:38 chessguy: ,String

22:38 clojurebot: java.lang.String

22:38 dysinger: richhickey just said his testing methodology is the "scream test" #heh

22:58 hermanChess: hello

22:58 stuhood: heya

23:44 arohner: clojurebot: paste

23:44 clojurebot: lisppaste8, url

23:44 arohner: clojurebot: *ahem*

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

23:44 clojurebot: excusez-moi

23:45 arohner: I have a goofy performance problem

23:45 lisppaste8: arohner pasted "perf problem" at http://paste.lisp.org/display/81335

23:45 arohner: I can run that test as many times as I like, and I get similar results each time

23:46 the first run is slow, and the final run is 2x faster than the first run

23:46 but between runs, I'm doing *nothing*

23:46 no reloading code, etc

23:47 hiredman: arohner: hotspot

23:48 arohner: I understand that if I had new code, it would take awhile to optimize

23:48 but why would it get slower between runs?

23:48 hiredman: oh

23:48 durka42: at the repl, the code is going to be compiled each time

23:49 hiredman: durka42: not in the example usage he has

23:49 arohner: but only my expression of (dotimes [i 10] (perf-test)) should be recompiled

23:49 durka42: yeah

23:49 and that shouldn't affect the optimization of performance-test...

23:50 what's in perf-test, out of curiosity

23:50 and by curiosity i mean i want to try this at my repl

23:50 hiredman: hard to say, there is always some jitter up and down in time's numbers

23:51 durka42: but you have to run with -server to enable hotspot at all, yes?

23:51 arohner_: sorry, computer trouble

23:51 I missed everything after "not in the example he has"

23:51 hiredman: hard to say, there is always some jitter up and down in time's numbers

23:51 arohner_: that's a 2x difference though

23:51 durka42: what's in perf-test? i kind of want to try this at my repl

23:51 arohner_: just a bunch of math

23:51 hiredman: durka42: actually the also appears to be a client version of hotspot

23:52 arohner_: multiplies divides

23:52 durka42: oh ok

23:53 stuhood: the example you show looks reasonable... it can take a few thousand iterations for hotspot to optimize something

23:53 arohner_: and I'm fine with that the first time

23:54 the problem is, if I keep running (dotimes [i 10] (perf-test)), I get the same distribution

23:54 durka42: i am not seeing that effect

23:54 hiredman: stuhood: he is asking about the large up and down in the numbers

23:54 arohner_: i.e. run 0 is always slow, no matter how many times I run the same expression

23:54 durka42: (defn perf-test [] (time (dotimes [i 20000] (+ 3 Math/PI (/ 10 7)))))

23:54 gives me pretty stable values for (dotimes [i 10] (perf-test))

23:55 arohner_: durka, I'm doing about a million multiplies and divides in each (perf-test)

23:55 durka42: paste it?

23:56 arohner_: that's kind of hard

23:57 let me see if I can find a more representative paste

23:58 clojurebot: paste

23:58 clojurebot: lisppaste8, url

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

23:58 arohner pasted "perf problem #2" at http://paste.lisp.org/display/81338

23:59 arohner_: so there, I run the exact same line, twice in a row

23:59 run 1 of each dotimes is slow, but run 10 of each dotimes is fast

23:59 stuhood: gotcha

23:59 arohner_: I'm ok with the first run 1 being slow. I'm not ok with the second run 1 being slow

Logging service provided by n01se.net