#clojure logs

2009-11-08

02:52somnium(.size (MongoProxy.))
02:52somniumoops
03:05stephenj~def ->
04:57ttmrichterWhat's the command set for the 'bot here?
05:01hiredmanclojurebot: how much do you know?
05:01clojurebotI know 467 things
05:01ttmrichterclojurebot: help
05:01clojurebothttp://www.khanacademy.org/
05:02ttmrichterAh.
05:02hiredman:D
05:02ttmrichterAnd I'm assuming , and ~ are special prefixes?
05:02hiredman~ is equivilant to clojurebot:
05:02clojurebotclojurebot is not a benchmarking platform
05:02ttmrichter~ commands
05:02clojurebotexcusez-moi
05:02ttmrichterAnd the ,?
05:03ttmrichter,(add 1 1)
05:03clojurebotjava.lang.Exception: Unable to resolve symbol: add in this context
05:03ttmrichterOops.
05:03ttmrichter,(+ 1 1 )
05:03clojurebot2
05:03hiredmanactually
05:03hiredman(+ 1 1)
05:03clojurebot2
05:03ttmrichterBeat you to it. :D
05:03hiredmannotice the lack of ,
05:03ttmrichterOh, no I didn't notice that.
05:04ttmrichterSo why is everybody putting , in front (including you)?
05:04hiredman(+ 2 3)
05:04clojurebot*suffusion of yellow*
05:04ttmrichter,(+ 2 3)
05:04clojurebot5
05:04ttmrichterSomebody is an Adams fan, I see.
05:04ttmrichter(/ 2 3)
05:04clojurebot2/3
05:04ttmrichter(/ 2.0 3)
05:05ttmrichter,(/ 2.0 3)
05:05clojurebot0.6666666666666666
05:05ttmrichter,(/ 2 30)
05:05clojurebot1/15
05:05ttmrichterSo is there a way to get a full set of instructions for clojurebot?
05:05hiredmannot so much
05:06hiredmanclojurebot: where are you?
05:06clojurebothttp://github.com/hiredman/clojurebot/tree/master
05:07hiredmanclojurebot: git 1c8e76b1a0e6616c780902a317a7ab9a8423288b
05:07clojurebotnewnew is now reify
07:55spuz,(filter seq '("abc" "" "def" "" "ghi"))
07:55clojurebot("abc" "def" "ghi")
07:55spuzis that a good way to filter out empty strings from a seqence?
07:57rhickey,(remove empty? ["abc" "" "def" "" "ghi"])
07:57clojurebot("abc" "def" "ghi")
07:57rhickeymight be clearer
07:57rhickeyalso, quoted lists are not idiomatic, use vectors
07:58tomojseems like remove empty? is a bit slower for some reason
07:58rhickeytomoj: good == clearest or fastest?
07:59tomojin this case the difference in speed is not really significant
07:59tomoj100-200ms on a 100000 element seq
07:59tomojso, clearest :)
08:00rhickeysomething that is clearer and slower today might be faster tomorrow, but will still be clearer
08:26spuzrhickey: thanks
09:00solussdis wrapping a function that calls a function that calls alter on a ref in a dosync sufficient to call it in a transaction? I have f2 that needs to run in a transaction, it is called by f1. can i (dosync (f1)) ?
09:01solussdnevermind- laziness was getting me
09:09chouserfolding defclass into deftype sounds very pleasant
09:25gerry`will there be no defclass only deftype in future?
09:27rhickeychouser: ah, good, someone is reading that :)
09:27rhickeyyes, I think very doable
09:27rhickeyand desirable
09:27rhickeyneed cemerick to chime in
09:28cemerickrhickey: on?
09:28rhickeyI think the ony gotcha will be people expecting the static aspects to update during dynamic development
09:28rhickeycemerick: http://www.assembla.com/wiki/show/clojure/Datatypes
09:28rhickeyfolding defclass into deftype, i.e. you get named class when AOT compiling deftype
09:28rhickeyunder: New ideas/scratchpad
09:29gerry` it seems cool
09:29rhickeyfor instance if you change the deftype and call new, you'll still get the AOT-compiled version
09:30rhickeyand (.field calls) will fail on non-AOT based instances
09:31gerry`but if i really want a changed AOT class?
09:31rhickeyOTOH, if (:field x) is as fast as (.field x) (at least for non-polymorphic sites), then why use (.field x)
09:31rhickeygerry`: compile again
09:31rhickeyand restart :(
09:32djpowellwhat is :field using now? is it not using case any more?
09:32rhickeydjpowell: it is backed by case, but there is not per-call-site caching of (:field x) calls
09:33rhickeyin my tests, when the type of x doesn't change at a callsite, the perf is identical to (.field x)
09:33rhickeyand of course, in real code using (.field x) the type of x isn't changing
09:34djpowellis the call site caching stuff described anywhere - i saw some checkins, but I didn't understand it
09:34rhickeycemerick: did you change all of your defstructs to defclasses or deftypes? and if the latter, to (.field x). If so maybe you could see if there is any perf disadvantage for you using (;field x)
09:35rhickeydjpowell: I just tried to describe it to some people the other day, in person, with diagrams, took over an hour
09:36gerry`rhickey: your new ideas/scatchpad should be put at top of wiki page
09:37rhickeygerry`: I don't want people to get confused by speculation, the top is now working documentation for working code
09:38cemerickrhickey: they all got replaced by defclass; they're implementing public named interfaces
09:38rhickeycemerick: oh, that's right
09:38rhickeyso you are not as good a test case then
09:38rhickeyfor deftype
09:39cemerickyeah, we're using it in only limited circumstances -- really, only where we'd otherwise be using regular maps with a stable set of slots
09:40cemerickI'm all for simplification though: right now, we have deftype, defclass, gen-class, proxy, and reify, which is quite a buffet to choose from if you're new.
09:42rhickeyso, other than user confusion about the lack of dynamicity of named things (a recurring problem), the only real sticking point is the clash between the factory fn name and the class name
09:43rhickeyseems a shame that people using Java can get (Foo. 1 2 3) where people using deftype dynamically will get (make-Foo 1 2 3) or something
09:43rhickeybut my.ns.Foo can't name both the class and the facgory
09:43rhickeyfactory
09:44rhickeywell, could but shouldn't
09:52avitalHello. I just started using Emacs/Slime with a remote Swank server and it keeps disconnecting. It may be something with my internet connection but I just wanted to check if anyone experiences similar issues...
10:00cemerickrhickey: w.r.t. "calls to (new Foo ...) will still use compiled class" -- perhaps the compiler should emit some hairy warning when loading a deftype is already defined in a compiled class?
10:02rhickeycemerick: If people aren't calling new or .field in Clojure code, i.e. using the factory fn and :field, then reloading a non-problem
10:03rhickeystatic name could just be for Java consumers
10:04rhickeyor serialization, that was a use case of yours, any thoughts?
10:04cemerickrhickey: true, but if you're not calling new or using .field, then there's no reason to be AOT compiling, either.
10:04cemerickor, AOT compiling with any potential of reloading, I should say
10:05rhickeycemerick: not sure I get that, if I AOT for consumption by JAva, no harm/no foul if I reload during dev
10:06rhickeyI just don't see it as a clear error
10:07cemerickOK, I'm reading "will still use compiled class" as meaning reloading will be a no-op for sites using new. Not an error, perhaps, but pretty darn surprising, I'd say.
10:08rhickeycemerick: why use (.field x) or new from Clojure code?
10:09rhickeynote calls to new inside methods will work properly, as will naked local field refs: field
10:10cemerickhrm, OK. In that case, I withdraw. :-)
10:10rhickeythe point of factory fns and fast (:field x) is to get people away from marrying AOT-static things
10:11rhickeynote that I don't disagree - the behavior of new and .field may be both surprising and disappointing upon reload
10:12rhickeyI get tired of explaining the static nature of Java classes and the problems with having/eating cake
10:13rhickeydeftypes + protocols should provide a high-performance dynamic alternative, with good bridges
10:13cemerickRight. Well, that's largely why I suggested the warning, but the need for it depends a lot on how closely people will hew to idiomatic usage of the classes generated by deftype/class.
10:14cemericki.e. :field rather than .field
10:14rhickeycemerick: I think the story has to be that new and .field are for interop consumption on the Java side
10:16djpowellif you are using new and .field for interop on the Java side, then having to recompile probably isn't too surprising
10:16rhickeydjpowell: exactly
10:19djpowellso... what code do you have to write in clojure for the call site caching stuff to kick in? is it keyword based access?
10:21rhickeykeyword callsites design diagram: http://www.assembla.com/spaces/clojure/documents/download/keywordcallsites.pdf
10:21djpowellok cool i'll take a look
10:21rhickeydjpowell: just (:k x) where x is a deftype/class instance
10:22rhickeythat diagram is not meant to be self-explanatory :), just what I had at hand
10:26ChousukeHopefully the JVM will be smart enough to optimise away most of the (identical? ret ...) checks, too.
10:28Chousukethough I suppose it'll have to have a check *somewhere*.
10:28rhickeyChousuke: yes, the fastpath presumes false, pipelining makes it 'free'
10:29rhickeythe truly amazing thing is that hotspot can dynamically lift the thunk 'get' body inline into the host method
10:29ChousukeThat's kind of counterintuitive, but nice nonetherless.
10:29Chousuke-r
10:30ChousukeJust goes to show that common sense assumptions about fast code hold less and less as processors and virtual machines advance :/
10:37Chousuke"Is the chart readable? no? Redesign."
13:03chouserWe just need alternate punctuation for the factory fn, vs the trailing . for 'new'.
13:08chouserSo (new Foo x) or (Foo. x) for java interop, (new-Foo x) or (Foo< x) for deftype
13:14ChousukeI suppose Foo: would be too easy to typo :P
13:14chouserbut much prettier than Foo<
13:15Chousukeif Foo weren't capitalised I'd just suggest make-* but make-Foo is kind of icky.
13:18mikehincheyI don't think make-Foo is that bad, and more clear than a special char
13:20chousergoogle search is now apparently crawling the clojure-log every few hours now
13:22hiredmanspecial
13:28solussdit's been doing that for awhile. :)
13:29hiredmanclojurebot: fun with vars is <reply>http://www.slideshare.net/mudphone/fun-with-vars
13:29clojurebotRoger.
14:43djorkwould it be possible to build a lazy seq using StringTokenizer?
14:43djorkI can do it all in one shot
14:44djorkwith loop
14:44chousersure could
14:44chouserusing lazy-seq directly is probably the most straightforward
14:44djorklazy-seq doesn't use any stack space?
14:45djorkwhen evaluated?
14:45chousera function that uses lazy-seq correclty and idiomatically will not consume stack space.
14:45djorkok
14:47chouser"StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code."
14:48djorkoh, that too I guess :)
14:48chouseryou could produce a lazy seq from StreamTokenizer as well, though you'd have to be careful about getting the InputStream or Reader closed correctly.
14:49djorkyeah
14:54djorkI'm looking at things like re-partition from clojure.contrib.str-utils
14:54djorkit seems like it would consume stack space
14:56djorkI see a pattern like (fn foo [] (lazy-seq (cons bar (foo))))
14:56djorkwhere foo is most definitely not in tail position... but is that not an issue with lazy-seq?
14:59chouserlazy-seq is a macro -- the expression inside it is put into a closure and returned
15:00chouserdo you know how trampolines work, either in Clojure or other languages?
15:01porpoiseCan someone help me with getting clojure to work with swank and jswat? I have it working with swank/Emacs but can't get it to open a port of external debugging
15:02porpoiseBill Clementson's site describes how to do it, but it's completely different from the automatic set up that was recommended to me as the current way to install it
15:02lisppaste8froog pasted "with-open and *out*, is this the way to do it?" at http://paste.lisp.org/display/90001
15:03djorkchouser: nope, not familiar with trampoline
15:03djorkhttp://gist.github.com/229461
15:03chouserfroog: looks good to me
15:04djorkdamn, trampoline means about 20 different things :) http://en.wikipedia.org/wiki/Trampoline_(computers)
15:05porpoiseWhat's the recommended way to install clojure with swank, and enable Jswat?
15:05chouserdjork: don't worry about trampolines -- if you already were familier I could use that to explain lazy-seq.
15:05djorkoh ok
15:06chouserdjork: your gist is close, but the body of the lazy-seq needs to always return a seq (or nil), not a string
15:06djorknext-tok will be nil in the false case of that if
15:06djorkbad style, probably
15:06froogchouser: I wish the extra binding wasn't necessary, but I guess there's great wisdom behind the different 'let' and 'binding'
15:06chouserdjork: oh! sorry, let me read again.
15:07djorkthere has to be an idiomatic way to express (if foo bar nil)
15:07chouserdjork: (when foo bar)
15:07djorkexcellent
15:07djorkyou know I was reading some article that said "Clojure doesn't have a faq, it has chouser"
15:08chouserheh
15:08djorkyou need a break man
15:08djorkclojure.contrib.chouser-vacation-fund
15:09chouserSpeaking of which, I'm off to read Narnia to the kids. Good luck, all.
15:09djorkedited: http://gist.github.com/229461
15:10chouserdjork: perfect, though I might recommend the name 'step' instead of 'next'
15:11djorkyes, now go be an awesome dad
15:58turbo24prgmorning
18:44skybound_i was wondering if i might suggest a small fix for repl_utils.clj; (source load-file) throws an NPE, as the symbol doesn't have a :file meta entry and .getResourceAsStream doesn't appreciate nil. i realize this isn't a critical kind of bug...
19:19chouserskybound_: fixed, thanks.
19:25skybound_chouser: you are welcome; and thanks for fixing, i wouldn't want to send in a contrib-agreement for such a small patch.
19:31skybound_i think this would be nice to have for java code as well, but for the moment i don't see an easy way to do it
19:32chouseryou mean for Clojure's own .java files?
19:33chouserthey're not usually in the .jar or on the classpath, so the files would be a bit tricky to find in the first place.
19:33skybound_no, i mean for any kind of java/class files where both are available to the classloader; like my own legacy java libs
19:34chouseroh, you have .java files in the classpath? I'm not a Java guy -- is that common?
19:34chouseryou can use 'show' to do some examination of the Java classes themselves.
19:35chousermaybe not the best chosen names. :-/
19:38skybound_it depends i guess, during dev i usually package source into the jars. for the moment my main usage of clojure is poking around in a java app via the repl.
19:39skybound_the idea is probably not worth the effort
19:41chouserwhen tracking down a Clojure behavior I often start with 'source' at the repl, but as I walk down the function calls end up at a java interop form, at which point I have to load the .java in an editor which is an unfortunate transition.
19:45skybound_right
20:48littleideaLearning clojure, philosophical question, when do you choose (. class-or-instance method-name args) or
20:48littleidea(.method-name class-or-instance args)? Is it just style or is there ever a clear preference for one over the other?
20:48hiredman.method-name is the prefered idiom
20:50littleideaok, thanks, that seems closer to the CLOS idiom
20:51hiredmaneven before .method-name existed I think (. class-or-instance (method-name args)) was prefered over (. class-or-instance method-name args)
20:52chouser(. i m (a)) is the oldest -- we've gotten steadily better since then. :-)
20:52chouserer, (. i (m a))
20:52hiredmanchouser: oh
20:52chouserI think. I could be remembering wrong. anyway, don't use either one.
20:52littleideagotcha
20:53chouserunless you're generating them in a macro. Sometimes they're a bit more convenient there.
20:54hiredmanbecause .foo is taken care of by the reader, and once you are in macro land you don't have the reader holding your hand
21:19chousernot quite
21:19chouser,(read-string "(.foo bar)")
21:19clojurebot(.foo bar)
21:19chouser,(first (read-string "(.foo bar)"))
21:19clojurebot.foo
21:19hiredmanhuh
21:19chouserit's actually expanded during macro-expand time, so you *can* use that form in a macro, it's just annoying.
21:20chouser,(macroexpand (list '.foo 'bar))
21:20clojurebot(. bar foo)
21:23chouser,(macroexpand (let [method 'foo] `(. bar ~method)))
21:23clojurebot(. sandbox/bar foo)
21:24chouser^^ simple
21:24chouser(macroexpand (let [method 'foo] `(~(symbol (str "." method)) bar)))
21:24chouser,(macroexpand (let [method 'foo] `(~(symbol (str "." method)) bar)))
21:24clojurebot(. sandbox/bar foo)
21:24chouser^^ annoying
21:59chouserhiredman: does *your* reader expand them? :-)
22:00hiredmannope
22:01hiredmanI think I was misrembering the part where the reader turns symbols naming classes into Class objects
22:20st3fani see parenthesis when i close my eyes
22:20st3fantoo much code
22:20st3fantotally sarting to like clojure
22:28st3fanis there a shortcut for (filter #(not (nil? %)) c) ?
22:29timothypratley2I think (remove nil? c) from memory
22:30timothypratley2,(remove nil? [1 2 nil 3])
22:30clojurebot(1 2 3)
22:34hiredman,(filter identity [1 2 nil 3 4])
22:34clojurebot(1 2 3 4)
22:34plunket,(loop infinite)
22:34clojurebotjava.lang.IllegalArgumentException: loop requires a vector for its binding
22:34st3fancool
22:34hiredman,(filter (comp not nil?) [1 2 nil 3 4])
22:34clojurebot(1 2 3 4)
22:34plunket,(loop (print "hello))
22:34clojurebotEOF while reading string
22:34plunket,(loop (print "hello"))
22:34clojurebotjava.lang.IllegalArgumentException: loop requires a vector for its binding
22:35st3faneven better would be a map function that would only return non-nil items
22:35plunket,(loop [print "hello"])
22:35clojurebotnil
22:35hiredman,(filter (complement nil?) [1 2 nil 3 4])
22:35clojurebot(1 2 3 4)
22:35plunket,(loop [5])
22:35clojurebotjava.lang.IllegalArgumentException: loop requires an even number of forms in binding vector
22:35plunket,(loop [5 8])
22:35clojurebotjava.lang.Exception: Unsupported binding form: 5
22:43wtetzner|nyx,(loop [x 10] (if (zero? x) (println "done.") (do (println (str "x = " x)) (recur (dec x)))))
22:43clojurebotx = 10 x = 9 x = 8 x = 7 x = 6 x = 5 x = 4 x = 3 x = 2 x = 1 done.
22:45st3fancan anyone give me an example of if-let ?
22:45timothypratley2,(if-let [a true] 10)
22:45clojurebot10
22:45wtetzner|nyx,(if-let [a false] 10)
22:45clojurebotnil
22:46st3fanoh so it is simply if the binding evaluates to a true value then the body is executed
22:46timothypratley2yup
22:46wtetzner|nyxit only executes what's in the if-let if the binding is non-nil and non-false
22:46st3fanok
23:03st3fanhm too bad if-let doesn't support multiple bindings .. would be nice if it would try all bindings and exec the body if they all returned a non-nil value