#clojure logs

2010-05-29

00:26timmorganloop/recur just about kicked my butt -- does it ever get natural?
00:26timmorgan...to write, that is
00:27replacayeah, I knocked out a couple in the last few days and it was pretty natural
00:27timmorganok, so there's hope
00:27timmorgan:-)
00:27replacabut also the more clojure you right, the less it seems you use loop recur
00:28replaca*write
00:28replacaargh :)
00:28timmorganI see
00:29replacamap/filter/for, etc. all come to hand much quicker
00:30timmorganand reduce? ...that's one I need to learn
00:32timmorganI get the concept, but using it in real life seems difficult
01:00timmorganwhy isn't there an any? function
01:00timmorgantesting for a non-empty vector, should I do (not (empty? vec))
01:01technomancytimmorgan: clojure inherited the unfortunately-named "some" function from CL instead of "any?". =(
01:01fusssany recent pointers on clojure + emacs?
01:01tomojI think the standard idiom you're looking for might be (if (seq vec) ...)
01:01tomojbut perhaps not
01:01fusssi have clojure-mode and swank-clojure alredy
01:01technomancyfusss: the latest swank-clojure readme should have you covered
01:01timmorgan,(seq [])
01:01clojurebotnil
01:01timmorgan,(seq [1])
01:01clojurebot(1)
01:01timmorganah yes!
02:33defnhello all
02:33defnanyone do any jruby + clojure?
02:34hamzagents, am i wrong to understand that i can use protocols to add support for calls like conj pop etc for custom data structures?
02:40bozhidardefn: why would you need to combine them?
02:42alexykJSON generators write things like "{\"9\":{\"jovenatheart\":1}}", how do I unquote field names' quote to write the raw string into a database?
02:44tomoj,(println "\"9\"")
02:44clojurebot"9"
02:45alexyktomoj: that doesn't unescape it
02:45alexykI mean the original
02:45tomojI guess I have no clue what you're talking about
02:45alexykso it does the right thing to print to screen, now I need to do the same into a value
02:46tomoj,(seq "\"9\"")
02:46clojurebot(\" \9 \")
02:46alexyktomoj: ah ok
02:47tomojthe string itself doesn't have backslashes in it, that's just the printed representation
02:47defnbozhidar: to have nice immutable stuff and the STM in jruby
02:47tomojs/printed/whatever/
02:47sexpbotthe string itself doesn't have backslashes in it, that's just the whatever representation
02:48bozhidardefn: why not just use clojure altogether?
02:48defnbozhidar: cause i can get away with it in a work project if i call clojure from jruby
02:49bozhidardefn: I guess you should just compile the clojure code and use it in the same manner you'd use it in a Java app, via JRuby's java interop
02:50defnbozhidar: yeah i suppose -- ive seen a few different approaches
02:50defnone of them was basically just talking to a REPL
02:50tomojtalking to a repl sounds wrong
02:50defnagreed
02:50defnwhich is why im asking :)
02:50bozhidar+ 1 - and it's ineffective as well
04:54maxhodakis the current consensus that clojure is 'fast enough' or are there major efforts to speed it up right now?
04:55tomojI believe the consensus is that you may sometimes have to do some work to get it fast enough in relatively small places, but don't take my word for it
04:57tomojI wonder why clojure isn't at http://wikis.sun.com/display/WideFinder/Results ?
04:58maxhodaktomoj: my experience has been that 90% of the time it doens't matter, and 7% of the time it matters you can make it fast enough with some work, but there's a wall
04:58maxhodaklike, you aren't going to writing games in clj anytime soon
05:10tomojI think clojure-mode should figure out which symbols are bound to functions in the buffer's namespace and color them appropriately
05:10tomojinstead of relying on a static list
05:16hoecktomoj: +1
05:17tomojit just struck me that inconsistent coloring seems worse than no coloring at all
05:35Chousukemaxhodak: Clojure is generally considered fast enough but I don't think Rich has stopped coming up with ways to make it faster :)
06:45naeuhas anyone else noticed that Clojure's byte behaviour is different in Clojure 1.2-SNAPSHOT compared with 1.1
06:45naeuConsider: (byte (bit-or (bit-shift-left 9 4) 1))
06:45hoecknaeu: yes
06:46hoeckmy workaround is to use (.byteValue 0xff)
06:46naeuHow might I create a byte of 8 bits where the first 4 bits are 9 and the last four bits are 1
06:48hoeck,(.byteValue 0x91)
06:48clojurebot-111
06:48naeuhoeck: hmmm, sure but it's not as descriptive as bit shifting
06:49naeuand I can't compose bytes using that method
06:49naeuI have a binary protocol where the first four bits are the message id and the next four bits are the params
06:50naeuand I was composing the full byte using bit-or and bit-shift-left
06:50hoeck,(.byteValue (bit-or (bit-shift-left 9 4) 1))
06:50clojurebot-111
06:50naeuah ok
06:51naeudo you have any understanding why we now have to drop into java interop to achieve something that was previously doable in pure clojure?
06:52GeoffSKemacs/clojure newbie - i have destroyed my binding to
06:52GeoffSK"{"
06:52GeoffSK- any suggestions how i fix the binding?
06:53naeufor example, the following looks strange: (byte-array 1 (.byteValue (bit-or (bit-shift-left 9 4) 1))))
06:53hoecknaeu: maybe to be consistent with int?
06:53hoeck,(int 0xffffffff)
06:53clojurebotjava.lang.ExceptionInInitializerError
06:56tomojperhaps in order to avoid accidental chopping
06:56tomoj
06:56hoeckbtw, I would not consider calling a jdk objects method to not be "pure clojure", especially when it comes down to bit twiddeling
06:57tomoj"pure clojure" seems like a useless term to me unless it means "no java interop"
06:57naeutomoj: sure, it just feels like .byteValue is a bit incongruous in that form
06:58hoeckGeoffSK: are you using paredit?
06:58naeuPerhaps this might be nicer: (byte-array 1 (byte-val (bit-or (bit-shift-left 9 4) 1))))
06:58GeoffSKhoeck: yes i am.
06:58hoeckGeoffSK: maybe: (define-key clojure-mode-map "{" 'paredit-open-curly)
06:58GeoffSKthe err message is : Symbol's function definition is void: paredit-open-brace
06:59GeoffSKhoeck: where do i put that?
07:00hoeckfirst try: m-x eval-expression
07:00hoeckto test wether it works
07:00tomojthere is no paredit-open-brace for me
07:00tomojparedit-open-curly for { and paredit-open-bracket for [
07:00naeuGeoffSK: somewhere in your .emacs although you could try it out in your live emacs with m-x eval-expression (M-:)
07:00hoeckits for paredit 21 and above versions
07:00hoeckor below
07:01GeoffSKsweet.
07:01GeoffSKit worked.
07:01naeuGeoffSK: if you're new to emacs you might consider the emacs starter kit: http://github.com/technomancy/emacs-starter-kit
07:01hoeckthen put that line in your init.el, after the (require 'clojure-mode) line
07:02hoeckand after the (require 'paredit) line (if there is one)
07:02GeoffSKthanks hoeck that was a lifesaver
07:03GeoffSKalso thanks naeu.
07:04naeuGeoffSK: I totally recommend the starter kit. I learned so much from using it.
07:09GeoffSKhoeck: i am putting it in my .emacs file, but i get Symbol's value as variable is void: clojure-mode-map
07:14tomojyou could use the paredit-mode-map
07:14tomojthe problem is that clojure-mode hasn't been loaded when you're trying to do the define-key
07:14tomojso the (require 'clojure-mode) line hoeck suggested will fix it too
07:15GeoffSKi am currently autoloading 'clojure-mode before the line i tried to add.
07:15tomojautoloading?
07:15GeoffSK(autoload 'clojure-mode "clojure-mode" "A major mode for Clojure" t)
07:16tomojyes
07:16tomojthat doesn't actually load clojure-mode
07:16GeoffSKoh.
07:16GeoffSKthe paredit-mode-map variant worked fine
07:17tomojthe autoload will make the clojure-mode function available and on the first call it will load clojure-mode
07:17GeoffSKi see. that makes sense.
07:17GeoffSKif i added a require then it would be loaded?
07:18hoeckyes
07:18tomojbut then your emacs startup would be more burdened
07:18tomojprobably not noticeably so, I'd hope
07:18tomojbut the more stuff you require at startup, the longer it will take
07:18GeoffSKi only use emacs for clojure anyway
07:20tomojfor now :P
07:20GeoffSKi know, i have started down a dark path
07:20GeoffSKappreciate the help.
07:21GeoffSKon a different matter, has anyone read the "Practical Clojure" book ?
09:11tomojis it good form to name your protocols like IFoo ?
09:11RaynesI hope not.
09:11tomojI thought I had seen that somewhere
09:11tomojso, I mean, hmm
09:12tomojyou end up taking good names out of people's vocabulary
09:12chousertomoj: That's somewhat normal for interfaces. I don't think a protocol naming style has been settled on yet.
09:12tomojI mean, if you have a User protocol, what do developers call their implementation of it?
09:12tomojmaybe I will use something like <Foo>
09:12tomojseems crazy
09:13chouserI think hiredman has recommended <Foo>, but I doubt it'll catch on.
09:13tomojI liked it when hiredman was recommending <foo> for defstruct
09:13tomojI think I'll join his doomed campaign
09:13chouserClojure has some interfaces named like adjectives. Sequable, Counted.
09:13tomojthe only official protocol I know of is InternalReduce
09:13chouseroh, maybe it was structs I was thinking of
09:15tomojthe docstring for defprotocol sounds like a rapid list of awesomeness
09:35tomojdo you think it's true that defprotocol, defrecord, deftype allow shallower trees of inheritance than java stuff?
09:36tomojI mean, when you hit a class, you can't inherit any further, right?
09:39tomojhmm, you can't have two protocols in the same namespace which share a method name, huh?
09:48Chousuketomoj: they're protocol *functions*. They work just like a normal function
09:49tomojyeah
09:59chousertomoj: yes, shallower.
10:02RaynesWhoa. I need sleep. I had to read that 5 times to realize that chouser wasn't calling tomoj a "swallower". :<
10:05dmiller2718rhickey: I rewrote the ClojureCLR wiki entry regarding proposed extensions to deftype and friends, to make it clearer what I think is necessary and what is optional. Whenever you have chance.
10:47alexyklancepantz: ping
11:22MoominpapaThis is going to sound like an odd question, but has anyone ever encountered "Invalid token d:"
11:23MoominpapaThe curious thing is, I'm getting it from trying to run leiningen repl. "D:" is my drive name (I'm on Windows) but I've carefully removed it from my path.
11:23Moominpapa^^classpath
11:24MoominpapaExact and incredibly ugly command is
11:24Moominpapajava "-Xbootclasspath/a:..\leiningen\lib\clojure-1.2.0-master-20100528.120302-79.jar" -cp "test;..\leiningen\leiningen-standalone.jar;lib\ant-1.6.5.jar;lib\classworlds-1.1-alpha-2.jar;lib\clojure-1.2.0-master-20100528.120302-79.jar;lib\clojure-contrib-1.2.0-20100528.120551-119.jar;lib\jline-0.9.94.jar;lib\jtidy-4aug2000r7-dev.jar;lib\junit-3.8.1.jar;lib\maven-ant-tasks-2.0.10.jar;lib\maven-artifact-2.0.10.jar;lib\maven-artifact-manager-
11:28mefestoMoominpapa: could you pastebin that, it looks like it was cut off
11:29Moominpapahttp://pastebin.com/VP8BD48q
11:33MoominpapaJust edited it. The following does it too
11:33Moominpapajava "-Xbootclasspath/a:..\leiningen\lib\clojure-1.2.0-master-20100528.120302-79.jar" -cp "test;..\leiningen\leiningen-standalone.jar" clojure.main -e """(use 'leiningen.core) (-main 'repl)"""
11:34MoominpapaWhere leiningen standalone is an uberjar compilation from trunk.
11:34MoominpapaDon't know if that matters.
12:12patrkrisconj is O(1) on both persistent lists, vectors and maps?
12:14chouserIt's always nearly O(1) or actually O(1), yes.
12:17chouserconj, I mean.
12:18patrkriswhen it is not actually O(1), what is it then?
12:18patrkrisnevermind, i'll just write "near-constant time"
12:19chouseryes
12:19chouseroh, I lied.
12:19chouserconj on a sorted map or set if O(log2 n)
12:20chouserconj on a vector is O(1)
12:20chouserwait, someone made a nice chart...
12:25Chousukechouser: I did, but I forget where it was posted :P
12:26chouserhttp://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html
12:27Chousukehuh, that table looks a bit weird in my browser
12:28Chousukethe titles are shifted to the left by one :/
12:28chouserit's really a solid chart.
12:28chouseroh. hm
12:28chouserI don't like to use 'head' or 'tail' -- their meaning seems vague and/or hard to remember for me.
12:37patrkrischouser: thanks for the chart
12:37patrkrisor Chousuke, I should say :)
12:39pdkwhich chart is this
12:39pdkfor the rest of us who may also make use of it :p
12:39chouserpdk: http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html
13:00Ankouhi, I'm getting the error "Exception in thread "main" java.lang.Exception: The syntax for defmulti has changed. Example: (defmulti name dispatch-fn :default dispatch-value) (tile_helper.clj:4)" but in line 4 of tile_helper is just the ns form just like everything else in the stack trace which belongs to my code is the first line of some ns form. I have no idea how to search for such an error so maybe you can help me?
13:07arkrosthI! For example, I can do (def do println) ((var do) "example") and it will work correct. How to do the same in let binding. I mean (let [do println] ...)
13:33arkrosthI! For example, I can do (def do println) ((var do) "example") and it will work correct. How to do the same in let binding. I mean (let [do println] ...)
14:15hoeckarkrost: `do' is a special symbol, so you may not be able to define a new binding for it with `let', because its treated specially by the reader and or compiler
14:17hoeckAnkou: currently, the only way is to either search in the tile_helper.clj (or all required/used files) for malformed defmulti expressions
14:18hoeckAnkou: or put println statements somewhere in the file to see until which statement the file loads correctly
14:18hoeckAnkou: or require the namespaces tile_helper.clj requires in its ns declaration on the repl to see which namespace actually causes the exception
15:00seoushiso I'm new to clojure and have limited experiance with lisps in general I was wondering if anyone would be interested in looking over some code of mine and giving general pointers http://github.com/seoushi/8-bit-game/tree/master/src/com/seoushi/
15:32arohneris there a way to detect when you're using slow math?
15:32arohneraside from using a profiler
15:33arohnervisualVM takes 30 mins to start profiling my app, and once started, I can't reload classes
16:02arohnerit appears there's no clojure.lang.Numbers.divide(int, int), but there's (int,float) and (int,double)
16:02arohneranyone know why?
16:03seoushiI've just been using the normal divide and then flooring it for integer math
16:03arohnerseoushi: I'm looking for the performance of primitive math. having no (int,int) means I get a reflection warning
16:04seoushiarohner, ah yeah. at this point in time I'm not optimizing anything (still learning)
16:05seoushiI haven't found anything built in for modulo yet tho
16:09arohner,(doc mod)
16:09clojurebot"([num div]); Modulus of num and div. Truncates toward negative infinity."
16:10seoushihmm I swear I tried that
16:12seoushilooks like enclojure by default installs clojure 1.0.. time to update
18:51herdrickso, what's the current way to do performance profiling in Clojure?
18:58riddochcherdrick: I suspect any java profiler would work, but there's also some handy functions in contrib...
18:59JorejiHey guys, is there some way to figure out which clojure functions/methods/macros are being called in an application and deploy the application compiled AOT with only those functions/methods/macros?
19:00herdrickriddochc: ah, in clojure.contrib.profile Those look pretty cool. Thanks.
19:14riddochcHere's a handy function I wrote, which has been quite useful so far: http://paste.lisp.org/display/110958
19:14tomojnifty
19:15tomojthat seems like it would make a common faq easy
19:15tomojer, hmm, not quite
19:21chouseraravind: did you figure out what you wanted to about primitive math?
19:22chousererm, sorry, wrong nick
19:23riddochctomoj: Which FAQ?
19:24tomoj(foo {:a 1 :b 2} {:a 3 :b 4 :c 5}) -> {:a [1 3] :b [2 4] :c [5]}
19:25tomojbut assoc-or-addto is not quite right for it it seems
19:26riddochcOh, not really. It's related, though. It's more like assoc than it is like merge-with.
19:27tomojwell, I was thinking it could be the f for merge-with, but nope
19:27tomojsome piece of the code for assoc-or-addto would work as the f for merge-with, I think
19:27tomojbut then there's also the problem where only one values is given for a key, hmm
19:27tomojI don't even remember a nice solution to that problem
19:28chouser,(reduce (fn [m [k v]] (assoc m k (conj (m k []) v))) {} (concat {:a 1 :b 2} {:a 3 :b 4 :c 5}))
19:28clojurebot{:c [5], :b [2 4], :a [1 3]}
19:31tomojah, (m k []), neat
19:32riddochcReduce is great. Once again.
19:55zakwilsonhttp://gist.github.com/418631 <-- I'm having some trouble wringing performance out of a quad-core machine. Would someone care to try this code on a 4+ core machine and compare results?
19:56zakwilsonIt seems like this should be absurdly parallel, but I'm barely getting any speedup when involving more than two cores.
19:59tomojhmm
19:59tomoj(apply concat (pmap ...))
19:59tomojis that OK?
20:00tomojpmap is "Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required"
20:02mitkokHey, guys. Anyone using vimclojure. I've got problem running the ng-server. It gives me : Exception in thread "main" java.lang.NoClassDefFoundError: com/martiansoftware/naulgun/NGServer
20:03zakwilsontomoj: I'm pretty sure it is. Wrapping the pmap in a doall just slowed it down slightly.
20:04zakwilsonActually... that's probably within the margin of error.
20:04Ankouis there a reason why it is forbidden to use a namespace with a definition which is also in the current namespace instead of just let the current namespaces definitions shadow the deifnitions of the used namespaces?
20:05zakwilsonIn any case, it sustains 390% CPU usage for the vast majority of its runtime.
20:08tomojah
20:08tomojI wonder how the pmap decides what to consume
20:08tomoj(apply concat ...) seems like it would only force the evaluation of one result at a time
20:09tomojbut it clearly doesn't, then
20:09zakwilsonIt appears to force the whole thing.
20:09tomojI guess I don't know what "semi-lazy" means, then
20:09tomojit races a bit ahead of the consumers or something?
20:10zakwilsonSomething like that.
20:10zakwilsonIf you don't consume anything, it doesn't produce anything. That much, I'm sure about.
20:10riddochcHmm.
20:10riddochc,(let [q (fn [&a] (coll? a))] (q "foo"))
20:10clojurebotjava.lang.Exception: Unable to resolve symbol: a in this context
20:10riddochc,(let [q (fn [& a] (coll? a))] (q "foo"))
20:10clojurebottrue
20:10zakwilson(do (pmap some-slow-f some-seq) nil) ;returns almost instantly
20:11riddochcEvidently, whitespace matters.
20:12zakwilsonThe real world requires my attention at the moment. I'll make a google group post about this later, as I'd really like to get this machine running on all four cylinders.
20:12tomoj,'&a
20:12clojurebot&a
20:13tomoj,(let [foo 3 bar 4] foo)
20:13clojurebot3
20:13tomoj,(let [foo3bar 4] foo)
20:13clojurebotjava.lang.Exception: Unable to resolve symbol: foo in this context
20:13tomojyes, whitespace matters..
20:13zakwilson,(let [&a "foo"] &a)
20:13clojurebot"foo"
20:13zakwilson& is a valid part of a symbol name
20:13zakwilsonso are numbers
20:13zakwilson,(let [foo3bar 4] foo3bar)
20:13clojurebot4
20:14tomoj,(let[foo3]foo)
20:14clojurebotjava.lang.IllegalArgumentException: let requires an even number of forms in binding vector
20:14tomojwhat I mean to say is that I don't think it should be surprising that whitespace matters :)
20:18riddochcWell, no, it's not surprising, I just hadn't expected & to be a valid character in a symbol.
20:19riddochcTook me a while to figure out why a (defn ... [... &rest] ...) wasn't working.
20:30tomojah, yeah
20:30tomojthere are many valid symbols which surprise me
20:30tomoj,'foo:bar
20:30clojurebotfoo:bar
20:30tomoj,'<3
20:30clojurebot<3
20:34riddochcHm. Having some difficulty with [... & rest] args, anyway.
20:38DeusExPikachuis there a repl-utils that runs with no errors for clojure-1.2.0?
20:43DeusExPikachunm
21:27riddochcHm. I guess I expected compojure's routing abilities to be a little less... minimalistic.
21:35tomojriddochc: clout?
21:36tomojthere's also moustache, which I find deliciously minimalistic
21:37tomojhmm, a multimethod would be cool, but the dispatch function will be the same always
21:37tomojso how do you make it extensible?
21:38riddochctomoj: Looks like compojure uses clout anyway.
21:38tomojyeah, that's what I meant
21:39tomojis clout much different than old compojure?
21:39riddochcI'm not sure.
21:39tomojwhat's wrong with minimalism? I mean, what features are missing?
21:39tomojI'm not saying there aren't any, just wondering what they are
21:41riddochcWell, I'm having a hard time getting it to handle something like /history/:version/:page
21:41tomojah, interesting
21:42riddochcThough the test for keyword-paths suggests that it should work...
21:43tomojin moustache I believe it'd be: (app ["history" version page] my-handler)
21:48riddochcLooks like it's time for me to read some code...
23:48trptcolini'm noticing some interesting behavior with clojure.test/are - http://gist.github.com/418759
23:51tomojthat's not how to use are
23:51tomojoh, sure it is
23:51trptcolinanyone have any insight into why do-template seems to work this way? (replacing bindings in both the template expression AND the template values)
23:52trptcolinso it works fine if i use z in my function - but the template variable x binds everywhere it occurs in the values in that first example
23:54trptcolinmaybe the solution is just not to write anonymous functions inside are, or just being careful with argument naming...
23:55tomojis it a do-template bug?
23:55tomoj#(* % %) would work here too, but, not really a solution
23:55trptcolinit feels like it to me, but i'm not savvy enough about what do-template does
23:56trptcolini get close to what i wanted by patching do-template to return (walk/postwalk-replace (zipmap argv values) expr))
23:56trptcolininstead of (walk/prewalk-replace (zipmap argv values) expr))
23:57trptcolinthat is, then "are" works as i expect.
23:59trptcolinhowever, adding a test case to that effect gives me: http://gist.github.com/418767
23:59trptcolinwhich kind of baffles me