#clojure logs

2009-10-06

01:13slyrus_hmm... what's the idiomatic approach when one feels like the would normally use CL's return-from construct?
01:56konrshould I read Let Over Lambda? Is it relevant to clojure programming?
02:00sdeobald_I don't have stu's book in front of me and my googling is failing me. How can (may?) I bind an anonymous function so that it can call/recurse on itself?
02:03slashus2(fn functionname [] (functionname))
02:04slashus2sdeobald: ^
02:04sdeobald_Thanks.
02:05slashus2Or you can use recur
02:06sdeobald_I'm actually making a weak attempt at converting an SICP exercise, so recur might be cheating and/or going too far.
02:11hiredmanwell, if you are doing sicp you might want to find a copy of the Y combinator
02:30sdeobald_hiredman: is there a book/paper by that name, specifically? Or do you just mean the concept in general?
02:31sdeobald_If anyone's interested: http://github.com/deobald/sicp-clojure/blob/master/1.1/sec_1_1_8.clj
02:31sdeobald_I'd love to hear thoughts on how to make the re-binding of 'sqrt-iter' go away.
02:37hiredmanno paper, I think someone implemented a clojure version on the google group
02:38sdeobald_Cool, thanks.
02:38hiredmanwell, no paper I was specifically refering to
02:38sdeobald_Gotcha
03:13Fossihi
03:41jdzsdeobald: what rebindingL
03:41jdz?
03:41jdzsdeobald: and i'm pretty sure you want to use recur
04:13Maddassdeobald: If you want to read up on the Y combinator, there's a paper titled "The Why of Y"
04:47konrWhat do you think of Common Lisp?
04:49ChousukeI tried it when I first heard about lisp but I never really got into it :/
04:52LauJensenkonr: Coming from C# to CL it has very thrilling. Coming from Clojure to CL it will feel very out dated and moronic
04:52LauJensens/has/was
04:53jdzwell, after doing some work stuff in Clojure for last 3 or so months coming back to CL seems like a dream come true, really
04:54jdzi never thought i would be so happy seeing a real backtrace
04:54LauJensenjdz, why ?
04:54RaynesI saw that coming.
04:54jdzwith restarts
04:54jdzjust my experience, yours will vary
04:54yasonkonr: It's more complex than I would desire from a language, and practically has no standard environment and libraries to run with (think Python, Java). But it has good, novel things too, if you're willing to immerse into it.
04:55RaynesI've got everything I need with Clojure. <3
04:55jdzexcept a backtrace you can find useful information in :/
04:56Chousukebacktraces in Clojure are horrible, yes :P
04:56Raynesjdz: I don't need that.
04:56Raynes\o/
04:56Chousukemy reader (which I still have to finish) have me exceptions wrapped in about 20 layers of RuntimeException for some reason ;(
04:57ChousukeI wish I had more time to work on Clojure stuff now
04:57ChousukeI'm always getting distracted by something else I need to do
04:58RaynesChousuke: Let's build that time machine I designed back in '02, and we can do just that.
04:58ChousukeRaynes: we can go back in time and incorporate cool Clojure features in Common Lisp.
04:59RaynesChousuke: Or we can kill all those associated with the creation of Common Lisp and create a Lisp with Clojure characteristics in it's place, and then return to the future to see how we modified the future.
04:59Chousukethat's a bit drastic.
05:00RaynesYes, but what do we have to lose?
05:00RaynesWe can just go back and not kill them.
05:00RaynesBesides that, they shall not die in vain.
05:00ChousukeThe creators of CL are still smart people. they would be more useful if we brainwashed them
05:01jdzRaynes: if you see Common Lisp around like it is, it means you have not gone back from the future and have not corrected the past
05:01jdzeasy as that
05:02Chousukeactually, if you changed the future you would forget that it ever was different
05:02Chousukeso you'd think you had failed.
05:02MaddasClearly none of you saw Star Trek (the recent movie).
05:02RaynesNot necessarily.
05:02RaynesThere would be new versions of ourselves when we return to the future, but we should still remain.
05:02RaynesAnyways, I'm actually going to bed, goodnight <3.
05:03konrbye
05:07LauJensenjdz, I must say I'm surprised that after using STM, atoms, agents, java libs and vector bindings that you would want to go back to CL
05:07jdzLauJensen: in the application domain i use i have no use for those, really. like, interfacing with a foreign code that is not thread-safe
05:08jdzand java libs suck balls
05:08jdzoh, did i say that out loud?
05:36Chousukegah :(
05:37Chousuketerminal crashed while I was compiling emacs
05:50LauJensenChousuke, where's your reader?
05:51Chousukestill on github :P
05:52LauJensenlink?
05:53Chousukelazy, huh :P
05:53Chousukehttp://github.com/Chousuke/clojure/tree/clojure-reader
05:54Chousukethe next step would be to make Clojure actually use it but that requires messing with the java code and I'm not quite sure how to proceed :/
05:54LauJensenlazy?? What does it take nowadays to search for 'Chousuke', then bring up your 'clojure-reader' project, 10 minz?
05:55LauJensenChousuke, I'm sure the Group can answer that question, ie. Rich is there
05:56LauJensenI see you didn't do a reader.clj - which files have you worked with ?
05:56Chousukeit's in src/clj/clojure/lang/reader.clj :P
05:56LauJensenaah gotcha :P
05:57Chousukeit's also based on my syntax-quote-macro modification of core.clj, which is on its own in the sq-macro branch
05:58LauJensenWhy *black-hole* ?
05:58ChousukeI just needed something I could conj onto that ignores the item
06:00LauJensenChousuke, Are you away that you can actually put documentation directly in the source, the so-called doc-strings? When you have function names like 'make-rh', 'quick-rh', etc, it really speeds up reading for other people looking at your source
06:00LauJensens/away/ware
06:00LauJensens/ware/aware
06:00Chousukeyes. I might document it later.
06:00Fossi"might" xD
06:00Chousukethe make-rh stuff will probably go away anyway
06:01LauJensenI'll commend you on your brevity of source, but it's really lacking in 1) no documentation, 2) an abundance of 'magic' numbers
06:02Chousukeyou mean the parameters to the advance function?
06:03LauJensenMore like "(<= 0xD800 ch 0xDFFF)" "(and (== 5 (count string)) (try (Integer/parseInt (subs string 1) 16)" "(not (<= 0 ch 0377))" etc
06:03Chousukeoh, right. that.
06:03Chousukethat's directly copied from the Java Reader. :)
06:03Chousukethough hm, I think it had comment s :P
06:03Chousuke-s
06:03Chousukeer, -' ' I mean
06:03LauJensenhehe
06:05Chousukethe symbol resolution stuff in the keyword handling is icky
06:06Chousukethere seems to be no good way to resolve a symbol to its full form without many conditionals ;/
06:10Chousukehmm
06:10ChousukeI'm using #() in the definition of the #() implementation function :P
06:10ChousukeI wonder if I'll have to fix that.
06:14danleinot if you're compiling clojure to clojure :p
07:58licoresseWhat is the best tool for looking up stuff in java doc?
07:58LauJensenI recommend: Your eyes
07:59licoressehaha
07:59LauJensen;)
07:59licoresseI remember a site, in the beginning of 2000, that let you search for keywords and presented examples where the keyword was present
08:00licoresseit was a great tool
08:00LauJensenGoogle you mean ?
08:01licoresseLauJensen: no... not goggle
08:02konrWhat's the clojure equivalent of CL's find-all?
08:04konrselect!
08:14LauJensenlicoresse, I can't determine if you're being serious or not - What tool could you want to go through a Javadoc? You always know which classes your looking, and a simple search gives you the description. What more is there?
08:15licoresseAh, my point was *examples*
08:15LauJensenaaah
08:15licoressegetting related examples to the Canvas class f.ex
08:15licoressehehe
08:16licoresse*eyes*
08:16chouserhttp://www.google.com/codesearch?q=Canvas+lang:java
08:17licoresseah nice!
08:18LauJensenThe first example is real nice, couldn't be any clearer than a one-liner
08:19chouseryeah, it's an excellent example of Java
08:19chouserpublic static final i forgot what i was doing...
08:46LauJensenIt's funny that my first version of brians brain attracted thousands of readers, but my transient rewrite has barely had 200 views :)
08:47ambientit might have something to do where it was linked
08:47ambientvisibility is king
08:48LauJensenI know - But I don't do anything to promote it, except put it on dzone, just to see what happends naturally
08:49ChousukeLauJensen: I don't see you in the clojure pipe ;(
08:50LauJensenThere's a Clojure pipe? :)
08:50Chousukeyes
08:51ambientthe original post is linked on reddit, the second one is not
08:51LauJensenYea, I wonder why
08:57konrHmmm, should I change a value set by (bindings)?
08:57konr*(binding)
08:57LauJensenkonr, in which situation ?
09:02konrLauJensen: I'm adapting some CL code that has several functions that access global variables. These variables can be overridden at a main function, so I'm not sure whether I should override them with (binding) or use references, setting them at the main function
09:03LauJensenkonr, I think you need to think the design through before you start coding, a 1-to-1 translation will probably give you very bad looking clojure code. If you're loading settings, it might be better to stuff them all in a hash-map, rather than have 100 global defs etc.
09:05Chousukeif your code is (or will be) threaded you must also take that into account.
09:10LauJensenyes, then you're looking at refs or atoms
09:14ChousukeI guess you could use alter-var-root though :/
09:14Chousukeif it really is one-time configuration
09:17LauJensen,(doc alter-var-root)
09:17clojurebot"([v f & args]); Atomically alters the root binding of var v by applying f to its current value plus any args"
09:17LauJensenNever used that
09:20Chousukechouser showed a neat use of it on the group
09:20Chousukehmm
09:21LauJensengot link ?
09:21Chousukewell, it was just (alter-var-root #'somefunc memoize)
09:23Chousuke,`defang
09:23clojurebotsandbox/defang
09:23Chousukenot visible in the sandbox I guess ;(
09:23Chousukeclojurebot: source
09:23clojurebotsource is http://github.com/hiredman/clojurebot/tree/master
09:24Chousuke,`de-fang
09:24Chousukehm.
09:24clojurebotsandbox/de-fang
09:24Chousuke,#'hiredman.sandbox/de-fang
09:24clojurebot#'hiredman.sandbox/de-fang
09:25Chousuke,(alter-var-root #'hiredman.sandbox/de-fang (fn [x] identity))
09:25clojurebot#<core$identity__4657 clojure.core$identity__4657@1e07f4b>
09:25Chousuke,(defn foo [x] x)
09:25clojurebotWrong number of args passed to: core$identity
09:25Chousukeoops
09:25Chousuke:(
09:25Chousukehiredman: sorry, I broke clojurebot
09:25Chousukehiredman: but you need to fix that hole
09:29Chousukehiredman: you need to make the defang function and the *bad-forms* global local to the sanbox-eval function :P
09:32Chousukehmm
09:32Chousuke,#=(alter-var-root #'hiredman.sandbox/de-fang (fn [x] (fn [form _] form)))
09:32clojurebotclojure.lang.Cons cannot be cast to clojure.lang.Var
09:34Chousuke,#=(alter-var-root #=(var hiredman.sandbox/de-fang) (fn [x] (fn [form _] form)))
09:34clojurebotclojure.lang.PersistentList cannot be cast to clojure.lang.IFn
09:34Chousuke,#=(alter-var-root #=(var hiredman.sandbox/de-fang) #=(fn [x] (fn [form _] form)))
09:34clojurebotclojure.lang.Cons cannot be cast to clojure.lang.IFn
09:34Chousukegah
09:34Chousuke,#=(alter-var-root #=(var hiredman.sandbox/de-fang) #=(fn [x] #=(fn [form _] form)))
09:34clojurebotclojure.lang.Cons cannot be cast to clojure.lang.IFn
09:35ChousukeI suppose I can't fix it :(
09:36Chousuke,#=(alter-var-root #=(var hiredman.sandbox/de-fang) #=(fn* [x] #=(fn* [form _] form)))
09:36clojurebotCan't resolve fn*
09:37Chousuke,#=(alter-var-root #=(var hiredman.sandbox/de-fang) #=(eval '(fn [x] (fn [form _] form))))
09:37clojurebotclojure.lang.PersistentList cannot be cast to clojure.lang.IFn
09:38Chousuke,#=(alter-var-root #=(var hiredman.sandbox/de-fang) #=(eval (fn [x] (fn [form _] form))))
09:38clojurebot#<sandbox$eval__2941$fn__2943$fn__2945 sandbox$eval__2941$fn__2943$fn__2945@1ab5e85>
09:38Chousukehmm
09:39Chousuke,4
09:39clojurebot4
09:39Chousukehooray
09:42Chousukethis particular security hole is really nasty though :(
09:44Chousukemight be better to kill Clojurebot before anyone really exploits it :P
09:50liwpChousuke: remind me: what does #= do?
09:50Chousukeread-time evaluation
09:50Chousukethat's not the main security hole though.
09:50liwpnope
09:50Chousukethe real hole is that I can override the sanboxing function...
09:51Chousukesandboxing*
09:51liwpI was just trying to figure out how you fixed clojurebot
09:51liwpafter breaking it
09:51Chousukewell, I notice that clojurebot doesn't bind *read-eval* to false
09:52ChousukeI'm still contemplating whether I should just kill Clojurebot or wait till hiredman responds ;(
09:53Chousukenoticed* ;P
09:54ChousukeI think it would be useful if you could mark vars as truly immutable
09:54liwpdefinitely in this case
09:55Chousukebut there are problems with that, too I guess.
09:55liwpit's also against the dynamic nature of lisp
09:55liwpbut that's more of a philosophical argument
09:56ChousukeI wonder if the bound-fn macro could help.
09:56liwpI haven't really been following the bound-fn conversation so far
09:56liwpI've never really been bitten by laziness in clojure so I haven't cared
09:57Chousukethough because you can basically change any var to anything it won't help much ;(
09:57Chousukeand somehow I doubt there's a way to disallow all possible ways of changing a var without crippling clojurebot completely
10:03Chousukehmm
10:05Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* (constantly {}))
10:05clojurebot{}
10:06Chousuke(alter-var-root #'hiredman.sandbox/de-fang (fn [form notallowed] (if (list? form) (when (not (some notallowed (tree-seq seq? #(let [a (macroexpand %)] (or (and (seq? a) a) (list a))) form))) form) form))))
10:06Chousuke,(alter-var-root #'hiredman.sandbox/de-fang (fn [form notallowed] (if (list? form) (when (not (some notallowed (tree-seq seq? #(let [a (macroexpand %)] (or (and (seq? a) a) (list a))) form))) form) form))))
10:06clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--2954$fn
10:06liwpDid you just disable all sandboxing from clojurebot?
10:06Chousukeno
10:06ChousukeI'm trying to fix it
10:07Chousukethe sandboxing was alredy disabled :P
10:07Chousuke,1
10:07clojurebot1
10:07liwpI mean the (constantly {}) bit
10:07liwpfair enough ;)
10:07Chousuke,(alter-var-root #'hiredman.sandbox/de-fang (fn [form notallowed] (if (list? form) (when (not (some notallowed (tree-seq seq? #(let [a (macroexpand %)] (or (and (seq? a) a) (list a))) form))) form) form)))
10:07clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--2966$fn
10:07Chousukegah
10:07Chousukethe defang function is too complex
10:08Chousuke,(alter-var-root #'hiredman.sandbox/de-fang (constantly (fn [form notallowed] (if (list? form) (when (not (some notallowed (tree-seq seq? #(let [a (macroexpand %)] (or (and (seq? a) a) (list a))) form))) form) form))))
10:08clojurebot#<sandbox$eval__2978$fn__2980 sandbox$eval__2978$fn__2980@ca1465>
10:08liwpdon't you need an extra layer of fn in that, because alter-var-root takes and fn that is applied to the var?
10:08Chousukeokay, now the defang thingy should be working
10:08liwpexactly
10:09liwpso what does it do exactly?
10:09liwpfilters out bad forms?
10:09Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* assoc 'this-is-a-test)
10:09clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$assoc
10:09liwpone more arg
10:10Chousukegah, it was a set originally...
10:10liwpheh
10:10Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* (constantly #{'this-is-a-test}))
10:10clojurebot#{this-is-a-test}
10:10Chousuke,this-is-a-test
10:10clojurebotjava.lang.Exception: Unable to resolve symbol: this-is-a-test in this context
10:10Chousukehmm.
10:11Chousuke,eval
10:11clojurebot#<core$eval__5182 clojure.core$eval__5182@4d8040>
10:11Chousuke*sigh*
10:11Chousukemaybe I should just give up
10:12liwpcan you rebind alter-root-var and thereby plug the hole?
10:12liwpfor the time being
10:12Chousukethat might break other things though
10:12liwpOTOH the bot is broken in any case so you can't really make things worse that way...?
10:13Chousuke,(eval '5)
10:13liwpit's gone to bed?
10:13clojurebot5
10:14Chousukenope :(
10:14Chousuke,(this-is-a-test '5)
10:14clojurebotDENIED
10:14Chousukeooh
10:14Chousukeokay, now I can perhaps fix it
10:14liwpso now you need to add all the bad forms to your set
10:15liwpmaybe remove your this-is-a-test as well ;)
10:15Chousuke,(alter-var-root #'hiredman.sanbox/*bad-forms* (constantly #{'intern 'eval 'def 'catch 'load-string 'load-reader 'clojure.core/addMethod 'hiredman.clojurebot/bot}))
10:15clojurebotChousuke: Excuse me?
10:15Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* (constantly #{'intern 'eval 'def 'catch 'load-string 'load-reader 'clojure.core/addMethod 'hiredman.clojurebot/bot}))
10:15clojurebotChousuke: Huh?
10:15Chousukegarr
10:16liwp,(this-is-a-test '0)
10:16clojurebotDENIED
10:17liwp,(+ 1 1)
10:17clojurebot2
10:17Chousuke,(var-set #'hiredman.sandbox/*bad-forms* #{'intern 'eval 'def 'catch 'load-string 'load-reader 'clojure.core/addMethod 'hiredman.clojurebot/bot})
10:17clojurebotChousuke: excusez-moi
10:18liwpI've never looked at the bot source, but it looks like that's not ever getting to the evaluator
10:19Chousukefortunately the channel is rather quiet at the moment :P
10:19Chousukeother than this bot-trickery
10:22Chousuke,(var-set #'hiredman.sandbox/*bad-forms* '#{intern eval def catch load-string load-reader clojure.core/addMethod hiredman.clojurebot/bot})
10:22clojurebotChousuke: Pardon?
10:22Chousuke:(
10:22liwp,(var-set + +)
10:22clojurebotjava.lang.ClassCastException: clojure.core$_PLUS___4443 cannot be cast to clojure.lang.Var
10:23liwp,(var-set #'+ #'+)
10:23clojurebotjava.lang.IllegalStateException: Can't change/establish root binding of: + with set
10:23ChousukeI wonder if the set thing is confusing it.
10:23liwpgood
10:23liwptry using set
10:23Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms conj 'catch)
10:23clojurebotChousuke: Titim gan éirí ort.
10:24Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* conj 'catch)
10:24clojurebotChousuke: Huh?
10:24liwpI don't think it likes you
10:24Chousukeheh
10:24rsynnottWhy does the bot speak Irish?
10:25liwprsynnott: it's a polyglot, it speaks french as well
10:25Chousuke,#=(alter-var-root #=(var hiredman.sandbox/*bad-forms*) conj catch)
10:25clojurebotChousuke: Titim gan éirí ort.
10:25liwpChousuke: since you're messing with the both, you might as well add finnish error messages
10:25Chousuke,#'hiredman.sandbox/*bad-forms*
10:25clojurebot#'hiredman.sandbox/*bad-forms*
10:26rsynnottParticularly unusual language for evil robots, though :)
10:26Chousuke??? I'm confused
10:26liwpChousuke: aren't you getting the args in the wrong order with conj here, i.e. it'll become (conj foo #{})
10:26Chousukeliwp: it's an altering function so it'll pass the thing to be altered as the first parameter
10:26liwpok
10:26Chousukeand any user-supplied args after that
10:27Chousukebut it seems it's even more broken now.
10:27liwp,(#'hiredman.sandbox/*bad-forms* 'this-is-a-test)
10:27clojurebotDENIED
10:28liwp,this-is-a-test
10:28clojurebotjava.lang.Exception: Unable to resolve symbol: this-is-a-test in this context
10:28liwp,'this-is-a-test
10:28clojurebotthis-is-a-test
10:28liwpduh
10:35Chousukeah, now I know why it doesn't like me
10:35Chousuke,catch
10:35clojurebotChousuke: It's greek to me.
10:36Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* (constantly #{'intern 'eval 'def 'load-string 'load-reader 'clojure.core/addMethod}))
10:36clojurebot#{intern load-reader load-string clojure.core/addMethod eval def}
10:36Chousuke~def alter-var-root
10:37Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* conj 'alterRoot
10:37clojurebotEOF while reading
10:37Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* conj 'alterRoot)
10:37clojurebot#{alterRoot intern load-reader load-string clojure.core/addMethod eval def}
10:37Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* conj 'alter-var-root)
10:37clojurebot#{alterRoot intern load-reader load-string clojure.core/addMethod eval alter-var-root def}
10:37Chousuke,(alter-var-root #'hiredman.sandbox/*bad-forms* conj :test)
10:37clojurebotDENIED
10:37Chousuke,(.alterRoot #'hiredman.sandbox/*bad-forms* conj :test)
10:37clojurebotDENIED
10:38Chousukeexcellent
10:42avitalHello Chous{er,uke} and friends. It seems that pr is supposed to print a value in the exact way the reader can read it. But (pr '(1)) prints (1) instead of '(1). Is this a bug?
10:42avital,(pr '(1))
10:42clojurebot(1)
10:44Chousukeavital: it's not a bug. pr is a function, so its parameter is evaluated
10:44Chousukeand if you read "(1)", you indeed get '(1)
10:44Chousuke,(read-string "(1)"
10:44clojurebotEOF while reading
10:44Chousuke,(read-string "(1)")
10:44clojurebot(1)
10:45Chousuke,(read-string "'(1)")
10:45clojurebot(quote (1))
10:54liwpChousuke: good job with the bot
10:55Chousukeyes. first I break it and then I fix it :P
10:55Chousukeall publicly on IRC
10:55Fossithat's the spirit
10:55liwpyou should've PM'd it
10:55liwpin the privacy of your own irc client
10:56ChousukeI don't know if it listens to PMs :/
10:56Fossiit does
10:56liwpit does
10:56Fossiit's more fun in public though :D
10:56liwpso what was wrong with (alter-var-root #'hiredman.sandbox/*bad-forms* conj 'catch)?
10:57Chousukeliwp: it turned out that an earlier function tests whether the message string contains "catch". :P
10:57liwpauts
11:35adityoola guys!
11:36adityohow do i remove a key/value pair from a map ..say {"lisp" "mcarthy", "Clojure" "Hickey"} and i want to remove lisp/mcarthy
11:37stuartsierra(dissoc *the-map* "lisp")
11:39adityocool, was thinking of writing somethings in the line of remove-if in CL
11:41adityothanks
11:42stuartsierranp
11:52chouserhiredman: thanks for mentioning "Evolution of Lisp". It's fascinating.
11:52chouser"This situation of unexpected performance is prevalent with Lisp."
12:09ambientone thing that really bothers me about functional programming and immutability is the performance issue
12:10ambientbut that's not such a huge thing because of the versatility. python is about 60 times slower than C. people (and I) still use it because it gets things done a lot faster
12:12stuartsierraWith any language, you write the code you want, then optimize a few critical sections, often by rewriting in another language. Clojure->Java, Java->C, C->assembly
12:14ambienti'd rather just use one language :/ but perhaps that's a pipe dream if i want both dynamicality(?) and performance
12:14chouserambient: keep the dream alive
12:15stuartsierraWrite a better compiler. Or a better VM.
12:15stuartsierraIt happens, just slowly. Almost no one writes assembly any more; C compilers are good enough.
12:16stuartsierraJava is getting there.
12:16chouserfalling back to mutable structures (like arrays) and sufficient use of macros (and other possible features like reify) we can hope to get *very* close to java speed while retaining many of clojure's abstractions, even in the small pieces of code where performance is most critical.
12:46tmountainas far as VM are concerned, hotspot is actually one of the best IMO
12:54konrIsn't there a version of (binding) that creates the variables, if they don't exist?
12:54technomancy(doc with-local-vars)
12:55ChousukeI haven't found much use for local vars :/
12:56technomancyyeah, it seems like the wrong answer
12:57stuartsierrakonr: the variables still have to be (declare ...)'d if you want to use them in other functions.
13:03technomancystuartsierra: I'm looking at your swank-clojure changes
13:03technomancyI'm not really understanding the clojure-maven-plugin
13:03technomancywhy does it take eleven Java classes just to perform clojure compilation?
13:04stuartsierraIt doesn't.
13:04stuartsierraclojure-maven-plugin does a bunch of different things -- compile source, compile tests, run main, run tests, run repl, run swank, generate docs...
13:05stuartsierraEach "goal" in Maven-speak needs its own class
13:06technomancyok, that's more than I've been using maven for so far.
13:06stuartsierraMost of them are small classes that call the methods in AbstractClojureCompilerMojo
13:07technomancyit would be nice if this stuff didn't have to be written in Java, but I've had a nasty time trying to gen-class maven stuff due to the wackiness in its classpath
13:08technomancy*class loader
13:08stuartsierraIt could be done, but then clojure-maven-plugin would have a dependency on Clojure, which is almost circular.
13:09stuartsierraMostly the plugin just invokes clojure.main with different arguments.
13:09technomancyas long as I'm not the one writing / reading it
13:09technomancycan't you do that from the pom though?
13:09stuartsierratechnomancy: not really, and not conveniently.
13:09technomancywe do that at work; seems a lot simpler
13:09technomancyfor AOT and test running
13:10stuartsierraThe point of Maven plugins is to keep the POM simple and declarative, not full of the procedural-type scripting one does with Ant.
13:11technomancyok, I'll try this out
13:11stuartsierraThe plugin code really isn't that bad; I was able to add the SWANK stuff without knowing much about Maven internals.
13:11technomancycool
13:11technomancydid you say something about wanting to start a repo for OSS clojure projects?
13:12stuartsierraIt was a half-formed idea to set up a Maven repo and encourage Clojure library developers to use it.
13:12technomancysounds good to me
13:12stuartsierraFirst I think we need to get swank-clojure and clojure-maven-plugin 1.1 into central.
13:13technomancyonce clojure 1.1 is out?
13:13stuartsierraNot necessarily.
13:13stuartsierraThen we need a Maven archetype for new Clojure projects, and get THAT into central.
13:13technomancyyou'd need a VPS or something to allow each contributor to have a user account, right?
13:13technomancyso they can push out releases
13:14stuartsierraDunno; I'm not that familiar with Maven deployment setups.
13:15technomancyI guess you could accept pubkeys from contributors all hooked up to the same user as long as you trust them
13:15stuartsierraBasically, I want to lower the barrier to creating & releasing Maven-enabled Clojure libraries, so that everyone does it.
13:15technomancyyes
13:16stuartsierraSo my plan of attack is 1. SWANK, 2. plugin, 3. archetype, 4. repository.
13:19technomancyI feel a little uneasy that jochu has a "start server refactoring" commit on the master branch with no further commits referencing it. =\
13:19technomancyyeesh; the centralized repos are slow.
13:20stuartsierrayou might want to ask jochu about that; maybe he has an older version that's stable enough for a 1.0
13:21konrIsn't it awesome? Clojure is even more concise than CL: http://scorciapino.com/pub/fotos/clj-vs-cl.png
13:23stuartsierraOn a related note, does the swank server target a particular version of SLIME? It would be nice to have that documented somewhere.
13:23technomancystuartsierra: slime doesn't really have versions
13:23technomancywell... no, it has 1.0, and that's it
13:23technomancyI think they've decided they don't do "releases"
13:24stuartsierracharming
13:24technomancybasically I have a fork of slime, and I set M-x clojure-install to use my fork, and I only update it when I've confirmed it works.
13:25stuartsierraOk. What if SLIME were packaged with swank-clojure?
13:25technomancythat's actually not a bad idea
13:25technomancysince it's just a single .el file
13:25technomancyactually, that's a great idea
13:26technomancymost of the code in slime is CL that's irrelevant anyway
13:26technomancyI was thinking about asking if they wanted to merge swank-clojure into slime, but I don't think that would ever happen
13:26technomancywhy not go the other way...
13:27Raynestechnomancy's brain is about to explode.
13:27stuartsierraEmacs couldn't load the .el code from a Maven JAR, but you could still tell Clojure users to get SLIME from the swank-clojure zip/tar distribution.
13:28technomancystuartsierra: well swank-clojure already bundles a .el file anyway
13:28stuartsierraRight.
13:28stuartsierraSo it should be easy enough.
13:29technomancyclojure-maven-plugin failed after twenty minutes of downloading asking for a gpg passphrase. =\
13:29stuartsierraHit enter.
13:29technomancyright; that made it fail
13:29stuartsierraweird, haven't had that problem
13:29technomancygpg: no default secret key: secret key not available
13:30technomancyI guess I need to generate one
13:30technomancyI just want to install it though. =\
13:30technomancythere we go
13:30technomancythis is why we need this in a centralized repo somewhere
13:31stuartsierraOr comment out the key-signing stuff in the clojure-maven-plugin POM
13:31stuartsierraI think you only need that to publish releases in central.
13:32technomancybug filed
13:34technomancystuartsierra: is there a way to see what goals are defined?
13:34technomancylike rake -T ?
13:36stuartsierraFor a single plugin, yes: "mvn help:describe"
13:36stuartsierraFor all plugins, no.
13:36stuartsierramvn help:describe -DgroupId=com.theoryinpractise -DartifactId=clojure-maven-plugin -Dversion=1.1-SNAPSHOT
13:36sproingiewhat a horrible horrible ui
13:36sproingiein a sane world that might be "mvn-help -p clojure"
13:37technomancydon't forget the -o "don't download the Internet again" argument. =\
13:38sproingieworst thing it would do is download the plugin itself which tends to be small
13:38stuartsierraIt never downloads the internet again.
13:40technomancyhmm... I can't get any of these goals to run
13:40sproingiemight have to be mvn-help -g com.theoryinpractise -p clojure
13:40technomancyI'll have to come back to this later
13:40stuartsierraok
13:40sproingiebut maven seems to have some way of figuring out groupIds of plugins automagically
13:41sproingieprobably some kind of index on <x>-maven-plugin
13:41stuartsierraif they're built-in or defined in the <plugins> section of your current project, it's just "mvn help:describe -Dcmd=clojure:..."
13:41stuartsierrasproingie: that's exactly what it does
13:42LauJensenstuartsierra, did you sort out file posting in your http agent yet ?
13:42stuartsierrano
13:42stuartsierraI seriously doubt I'm going to.
13:42LauJensenoh, why the change of heart ?
13:43stuartsierraI looked at what it entails. There's Base64 encoding, MIME headers, etc.
13:43stuartsierraThe Apache HTTP library handles that well already. I'm not going to reimplement it.
13:43LauJensenSoftened your knees a little bit, did it? :)
13:43stuartsierraexactly.
13:43LauJensenIt's fine, apache libs work without problems anyway
13:44stuartsierramaybe someday I'll rewrite HTTP agent based on Apache's client, but I've got bigger fish to fry right now.
13:45LauJensenAlright
13:45technomancythat'd have to wait till Dependencies Work anyway
13:45stuartsierratruth, hence my recent enthusiasm for Maven
13:46LauJensenAre you guys working on something with Maven ?
13:49stuartsierra(1:16:42 PM) stuartsierra: Basically, I want to lower the barrier to creating & releasing Maven-enabled Clojure libraries, so that everyone does it.
13:49stuartsierra(1:16:47 PM) technomancy: yes
13:49stuartsierra(1:17:37 PM) stuartsierra: So my plan of attack is 1. SWANK, 2. plugin, 3. archetype, 4. repository.
13:53ambientreading through clojure.core this sentence really took a long time to parse :P "Evaluates exprs one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil."
13:55hircusI think parenthesizing or quoting the first "or" would help readability a lot
13:57LauJensenstuartsierra, thanks, I'm awake now
13:57LauJensenLet me know when you have something we should try out
13:58stuartsierraYou can try the latest from github: http://github.com/jochu/swank-clojure and http://github.com/talios/clojure-maven-plugin
14:01LauJensenI'll have a look
14:04LauJensenstuartsierra, looks like you're filling a void in clojure-land, weee :)
14:04liwp`~library
14:04stuartsierrafalling into the void, more like
14:05liwp`huh, where's clojurebot? did hiredman take it off-line for patching?
14:27LauJensenliwp, yea he's probably in the shop :) Chousuke messed him up a little bit
14:28LauJensenliwp or actually looking through my log, its possible he just didn't recover from the ircd's restart
14:28ChousukeLauJensen: clojurebot already returned ;P
14:29Chousukethough now I have to fix him again
14:29LauJensenChousuke, so you're saying, check the user list before analyzing logs? :)
14:29hiredmanI did nae restart it, just had it reconnect and rejoin
14:29Chousukeor hm, I suppose the process itself survivved.
14:30Chousuke,(alter-var-root error)
14:30clojurebotDENIED
14:30Chousuke-v
14:40dnolencgrand: been thinking a little bit about enlive again, specifically nesting template/snippets. You said this would be slow. Would it make sense to cache the fast representation to disk?
14:40cgranddnolen: I saw you forked it again :-)
14:41cgrandI don't remember what was your use case.
14:42dnolenjust dynamically selecting sub templates from a template.
14:42dnolentemplate inheritance is what I wanted i realize.
14:46dnolencgrand: http://groups.google.com/group/clojure/msg/4469f364b0b7c09f
14:46dnolenthis was your response
14:48cgranddnolen: thx
14:51cgrandthere are two things that makes a dynamic snippet like the one in your sample code slow: parsing and pre-serializing. Parsing overhead is easily worked around by loading your html once.
14:51dnolencgrand: does it make sense to cache the parsed content to disk?
14:53cgranddnolen: I don't think
14:53woobyhello, would anyone happen to know why this gives me 'malformed member expression?' (.. os write (to-byte-array file) 0 (.. file length))
14:53dnolencgrand: k, what do you mean by pre-serializing?
14:56liwp`wooby: (..file lenght) seems broken to me
14:56liwp`you should avoid the .. forms if you can
14:56liwp`use -> instead
14:56woobyah, does that do the same thing?
14:57liwp`in effect yes
14:57liwp`so something like (-> os write (to-byte-array...))
14:57kotarakBut it also allows for clojure functions and macros... (-> x .methodCall clj-fun (a-macro with other args))
14:58cgranddnole; once a html tree is loaded, each node is annotated with its serialization. Hence when Enlive serilaizes the output of a transformation, if a node is untouched by the transformation it can skip walking it and directly emits the cached serialization.
14:58cgranddnolen: that's for you ^^
14:58woobyi see... thank you
14:58liwp`wooby: the 0 in the middle of your .. form looks suspect as well
14:59woobyliwp: what i'm trying to do is write a file's contents to a socket's output stream
14:59liwp`are you trying to call write on os and everything else is just a set of arguments to the write call?
14:59woobyit's entirely possible i'm going about it entirely the wrong way
14:59woobycorrect
14:59dnolencgrand: i see. so how would you handle template inheritance using Enlive? :)
15:00liwp`wooby: you should have something like (.write os <args>)
15:00woobyhttp://gist.github.com/203318 that's the whole thing so far... forgive the style, i'm sure it sucks
15:00woobybut i appreciate any and all feedback
15:00liwp`let's see: (.write os (to-byte-array file) 0 (.length file))
15:00liwp`try that
15:00cgranddnolen: could you be more specific on what you call template inheritance?
15:01liwp`wooby: so whenever you want to call a method you should use (.method object)
15:01liwp`except for static methods it would be (Class/method ...)
15:02liwp`wooby: I see a lot of .. forms in your code and most of them are wrong, e.g. (.. sock close) should be (.close sock)
15:02cgrandbut this annotation phase can be moved out of snippet* and put into html-resource, this would make dynamic snippets lighter
15:02liwp`wooby: I guess the .. form works as well, but it's not idiomatic
15:02woobyok thanks, it's what i'm aiming for
15:02woobyjust going off the book so far
15:03ambientit looks like a lot of .java in clojure/src/jvm is machine generated?
15:03liwp`ambient: nope
15:03ambienthuh, weird
15:03liwp`or possibly some of the invoke defs
15:04dnolencgrand: for example, 3 column layout. that's one template. then I have a nav template. In one app I'd like to put this in column 1 in the base 3 column template. Nav template supports showing different widgets. Each widget is itself a template.
15:05liwp`wooby: in the past people used to write (.. my-obj meth1 meth2 meth3), (. my-obj method) and (new Foo). These days the fashion is to write (-> my-obj m1 m2 m3) (.method my-obj) and (Foo.) instead
15:06cgranddnolen: have to go, can we continue by mail? Can't you achieve what you describe by function composition?
15:06liwp`wooby: the (.. os...) form seems to be the only broken bit in the gist (haven't tried running it)
15:06woobyliwp: got it, thank you
15:06kotarakcgrand, dnolen: would keep also informed?
15:06kotarakI'm also interested in this!
15:07woobyliwp: thanks, i managed to fix it thanks to your help, now working on another bug
15:07Chousukethe .. form is still fine sometimes though.
15:07dnolencgrand: you're probably right, I've just started thinking about this again.
15:07Chousukeyou can't access statics through -> IIRC.
15:07Chousukeor hm
15:07Chousuke,(-> Math .PI)
15:07clojurebotjava.lang.IllegalArgumentException: No matching field found: PI for class java.lang.Class
15:07Chousukeright.
15:07kotarakChousuke: ,(-> Math/PI)
15:07kotarak,(-> Math/PI)
15:07clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$--GT-
15:08kotarak,(-> Math/PI identity)
15:08clojurebot3.141592653589793
15:08Chousukekotarak: yeah, but that won't work if it's nested somehow... on second thought, is that even possible? :P
15:08kotaraknested?
15:08Chousukenever mind. I don't think it's possible :)
15:09kotarakI don't understand the nested.
15:09raekmy first library: http://github.com/raek/clojure-sandbox/blob/master/src/com/github/raek/xml_with_xmlns.clj
15:09ChousukeI mean (-> foo .bar .static ...)
15:09raekextending clojure.xml with xml namespaces
15:09kotarakChousuke: You mean .bar returns a class, which you want to use as part in front of the "/"?
15:10liwp`Chousuke: shouldn't that just work, i.e. can't you just call the static method on the instance rather then the class?
15:10Chousukeliwp`: yeah, I guess you can
15:11raek{:tag :foo:bar :attrs {:xmlns:foo "http://example.com/ns&quot;}} => {:tag :http://example.com/ns/bar :attrs {}}
15:12kotarak,(-> "123" Integer/valueOf (.valueOf "567"))
15:12clojurebotjava.lang.IllegalArgumentException: No matching method found: valueOf for class java.lang.Integer
15:15liwp`kotarak: so you can't call a static method on an instance...
15:15chouseruh
15:15kotarakliwp`: It seems like this is not possible, no. Any Java gurus around?
15:15raek(anyone here using clojure.xml and/or xml namespaces?)
15:16criosin Java you can call a static methond on an instance
15:16woobysweet, this little webserver totally works now... thanks everyone for your help
15:16woobyhttp://gist.github.com/203329
15:17kotarak,(.valueOf 5 "123")
15:17clojurebotjava.lang.IllegalArgumentException: No matching method found: valueOf for class java.lang.Integer
15:17kotarakhmmm
15:17liwp`kotarak: in java you're definitely allowed to write Foo f = new Foo(); f.staticMethod();
15:17liwp`it's not good style, but it's allowed
15:17kotarakI believe you. But it obviously doesn't work in Clojure.
15:17liwp`yep
15:19mgarriss(n00b warning) why does this: http://pastie.org/644262 produce this error: "java.lang.IllegalArgumentException: recur arg for primitive local: x must be matching primitive"
15:21kotarakmgarriss: Math/pow is double, while (/ x y) is maybe integer? (Just guessing)
15:22chouserpow returns a primitive double. / will only return a primitive double if both x and y are also
15:23chouserSo (double (/ x y)) or (/ (double x) (double y))
15:23kotarakThe code is (/ x 10). So maybe (/ x 10.0)?
15:23raekanyway, if you are interested in taking a look at a newbie's code: http://github.com/raek/clojure-sandbox/blob/master/src/com/github/raek/xml_with_xmlns.clj
15:24raekall kinds of comments are welcomed
15:25mgarrisshmm, the (/ x 10.0) didn't work
15:25kotarakmgarriss: try chouser's tip
15:26mgarrissthat was it!
15:26Chousuke(/ x (double 10)) should be enough, since x is already double
15:26mgarrissthx all
15:26chouserChousuke: yep, hadn't read the paste yet. :-{
15:26chouserer, :-P
15:29mgarrissi guess i'm not clear as to why i needed to do that
15:30liwp`,(class (/ 10 2))
15:30clojurebotjava.lang.Integer
15:30liwp`,(class (/ 10 2.0))
15:30clojurebotjava.lang.Double
15:30chousermgarriss: when you create a local (via let or loop), if the value assigned to it will be a primitive, the local itself will be a primitive.
15:30mgarrissbut shouldn't have x already been a double?
15:30chouseryes, x was indeed a primitive double.
15:31chouserso the problem was the recur, where you were trying to assign the result of (/ x 10) back to x
15:32chousernumeric literals in Clojure are boxed, so / sees a primitive double (x) and a instance of Integer (10)
15:32mgarrissboxed?
15:32chouserthat causes / to compile to a form that would return a Number
15:33chouserboxed means non-primitive -- an instance of a Class that extends Object vs. a primitive which isn't an instance of any class type, it's a special built-in Java primitive.
15:34mgarrissthis is all in an attempt to learn some more clojure and to prove this: http://en.wikipedia.org/wiki/Kaprekar_constant
15:35mgarrissi love clojure already, ruby is paying the bills but driving me nuts
15:37criosa "boxed" object lives in the "heap" memory, and it is garbage collected. A primitive datum lives in the stack
15:37hoeck1mgarriss: mhh, strange, it disappears when wrapping the first recur form in a double: (recur (double (/ x 10)) ....)
15:38criosand it is not collected
15:38chouserso (double (/ x 10)) or (/ x (double 10)) should work.
15:39mgarrisschouser: i used the former
15:39chouseryou can experiment with repl-utils/expression-info to see details about the return types including (primitive or not) of expressions.
15:39chousermgarriss: the latter probably has slightly better performance, if that matters.
15:39mgarrissit does, i was just about to ask about that
15:40chouser(double (/ x 10)) will box the x, do the math, return a Double (boxed), and then unbox it to a double
15:41chouser(/ x (double 10)) will use an unboxed 10, do primitive math on it and use the result directly.
15:41mgarrissnew version (i also had to subtract 1 from number of digits): http://pastie.org/644313
15:41ChousukeI think (dec x) is more idiomatic than (- x 1)
15:42mgarrissgood call
15:42mgarrissis dec more efficient then (- x 1) ?
15:42mgarrissi imagine it is
15:43chouserprobably.
15:43Chousuke~def dec
15:43mgarrissit's certainly easier to read
15:43chouseryou should test any performance claims, as the JVM can do unexpected magic (or fail to perform expected magic)
15:43Chousukewell, apparently it uses some java magic... so maybe
15:44chouserbut having said that, it looks like (double 10) may be unboxing that Integer every time.
15:45chouseryou might try (def digits (let [ten (double 10)] (fn [number] ... (/ x ten) ...)))
15:46criosso the unbox occurs just one time?
15:48chouserright. the closure stored in digits would then close over the primitive 'ten' which would be used in the loop. Surely the JVM can perform magic on that. :-)
15:48chouserbut again, you'd have to test on a fully warmed-up JVM to be sure
15:49spuzI'm having a bit of a weird problem with a method on a class not being found. Is there a way to enumerate all of the instance and static methods on a class from clojure?
15:49herdrickHi. I'm wanting to use union and intersection for Maps (hashes).
15:50chouserspuz: try clojure.contrib.repl-utils/show
15:50technomancyspuz: in slime it's C-c I
15:50herdrickIt looks like I can use clojure.set.project to make something that works like this but it's ugly
15:50technomancyor use repl-utils
15:50herdrickLike this:
15:50herdrick(project [map1 map2] (intersection (set (keys map1)) (set (keys map2))))
15:50mgarrissugh, now i need an undigits that undoes digits
15:53hiredmanI was just reading a pdf that discussed the chaotic nature of performance on today's platforms
15:56criosmaybe too many layers
15:57hiredmanwell, you get chaotic (extremely sensitive to initial conditions) performance behaviour from cpus even, but I'm sure the jvm's optimizing (or not) doesn't help
15:58herdrickpart of the problem is that what I want isn't really just an intersection of the keys of the maps,
15:59herdrickbut rather new maps of a subset of each original map
15:59clojurebotnew Class(x) is (Class. x)
16:01herdricksorry: new maps, each a subset of one of the original maps,
16:01herdrickusing the keys found in both
16:04crioscloning the values of those keys?
16:06kotarakherdrick: this are probably not well-defined operations. What happens in this case: (hypothetical-map-union {:a 2 :b 3} {:b 4 :c 5})?
16:07mgarrissundigits was much easier: (defn undigits [numbers] (reduce + (map #(* %2 %) powers-of-10 (reverse numbers))))
16:08chousercould use * instead of #(* %2 %)
16:08kotarakherdrick: union is merge, btw. intersection can probably be done with select-keys.
16:08herdrickkotarak: sorry, i think my irc client is doing something funny with your code. What's the second key of your second Map?
16:09kotarakherdrick: colon c (or (keyword "c"))
16:09kotarak,(merge {:a 2 :b 3} {:b 4 :c 5})
16:09clojurebot{:c 5, :a 2, :b 4}
16:09herdrickAlso, yes, map-union would need to be like merge or merge-into
16:09kotarak,(select-keys {:a 2 :b 3} [:b])
16:09clojurebot{:b 3}
16:10kotarak(where [:b] is the intersection of the keys of the two maps)
16:11kotarak,(let [m1 {:a 2 :b 3} m2 {:b 3 :c 4}] (select-keys m1 (clojure.set/intersection (set (keys m1)) (set (keys m2)))))
16:11clojurebot{:b 3}
16:12mgarrisschouser: good call, not sure what i was thinking there
16:14herdrickkotarak: but you are only preserving the values for m1 there
16:15herdrickkotarak: i want both
16:15crios,(class (seq []))
16:15clojurebotnil
16:15kotarakherdrick: that's where the "not well-defined" comes into play.
16:15herdrickkotarak: the code I pasted in above does that
16:15criosWhy is it nil? Shouldnt'it be an empty sequence?
16:15herdrickhere it is again:
16:15herdrick(project [map1 map2] (intersection (set (keys map1)) (set (keys map2))))
16:15chousercrios: seq on an empty collection returns nil
16:15hiredmancrios: what does (seq []) return?
16:16herdrickkotarak: well, it only takes a careful definition... :)
16:16herdrickbut thanks,
16:16kotarakherdrick: then it's not "intersection" of maps
16:16kotarakherdrick: your code must return something different
16:16herdrickright, it returns two maps
16:16criosseq [] returns null, mm thank you
16:17herdrickso it isn't really an intersection
16:17herdrickit
16:17herdrickit's something else
16:17herdrickBTW I just used clojure.set/project because it seems to do what I wanted but I don't really understand the short description of it
16:18kotarak,(let [m1 {:a 2 :b 3} m2 {:b 3 4} intersected-keys (clojure.set/intersection (set (keys m1)) (set (keys m2)))] (vector (select-keys m1 intersected-keys) (select-keys m2 intersected-keys)))
16:18clojurebot3
16:19kotarak,(let [m1 {:a 2 :b 3} m2 {:b 3 :d 4} intersected-keys (clojure.set/intersection (set (keys m1)) (set (keys m2)))] (vector (select-keys m1 intersected-keys) (select-keys m2 intersected-keys)))
16:19clojurebot[{:b 3} {:b 3}]
16:22herdrick,(let [m1 {:a 1 :b 2} m2 {:b 3 :c 4}] (clojure.set/project [m1 m2] (clojure.set/intersection (set (keys m1)) (set (keys m2)))))
16:22clojurebot#{{:b 2} {:b 3}}
16:22herdrickkotarak: that's the way i was doing it
16:23kotarakherdrick: well, ... when it works. :) It's shorter.
16:23herdrickkotarak: but your way is possibly superior
16:23herdrickkotarak: thanks for the help
16:23kotarakherdrick: maybe, maybe not. But it's good to know select-keys :)
16:24herdrickkotarak: it sounds like you know more about sets in Clojure than me. Can you tell me about clojure.set/project ?
16:24herdrickI don't get what xrel is in the docs
16:24kotarakherdrick: oehm... actually never used it :P
16:24kotarakLet's see.
16:24kotarak(doc clojure.set/project)
16:24clojurebot"([xrel ks]); Returns a rel of the elements of xrel with only the keys in ks"
16:24herdrickkotarak: me neither until now
16:25kotarakJust watching Joshua Bloch's "How to Design a Good API and Why it matters": don't use cryptic abreviations....
16:26herdrickkotarak: indeed
16:28kotarakWell. It simply maps select-keys over the xrel part.
16:28kotarakAnd turns the result again into set. (Which might not be what you want.)
16:28kotarak,(let [m1 {:a 1 :b 2} m2 {:b 2 :d 4}] (clojure.set/project [m1 m2] (clojure.set/intersection (set (keys m1)) (set (keys m2)))))
16:28clojurebot#{{:b 2}}
16:28herdrickkotarak: yeah, except for the "turns the result again into set" part
16:29herdrickkotarak: that breaks my code when the two new maps are the same
16:29kotarakexactly
16:29herdrickkotarak: exactlt!
16:29herdricksorry, exactly!
16:29herdricklol
16:29herdrickkotarak: i'm going with your version
16:29herdrickkotarak:thanks
16:30kotarakherdrick: np
16:37mgarrisshow do i combine 2 vectors into one?
16:38chouser,(into [1 2 3] [4 5 6])
16:38clojurebot[1 2 3 4 5 6]
16:38mgarrissthx
16:39hircus,(reduce conj [1 2 3] [4 5 6])
16:39clojurebot[1 2 3 4 5 6]
16:39mgarrisshow do i create a vector of some given size containing all zeroes?
16:39clojurebotwith style and grace
16:40chouserinto should use transients while reduce conj I think would not.
16:40mgarrissi don't really understand the reduce method
16:40chouser,(vec (repeat 12 0))
16:40clojurebot[0 0 0 0 0 0 0 0 0 0 0 0]
16:41hircusfor each element in the second sequence, it applies conj to the first sequence and that element, and then repeats with the resulting sequence and the rest of the second sequence
16:41hircus,(doc reduce)
16:41clojurebot"([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val is supplied, returns the r
16:42mgarrissi see, very cool
16:42hircusmgarriss: this is probably a more obvious example: ,(reduce * [1 2 3])
16:42hircus,(reduce * [1 2 3])
16:42clojurebot6
16:42kotarakhilarious : http://www.youtube.com/watch?v=aAb7hSCtvGw#46m0s
16:43kotarakrather http://www.youtube.com/watch?v=aAb7hSCtvGw#t=46m0s
16:43hiredmanclojurebot: botsnack
16:43clojurebotthanks; that was delicious. (nom nom nom)
16:44hircusor defining factorial this way
16:44hircus,(reduce * (take 5 (iterate inc 1)))
16:44clojurebot120
16:49mgarrissi can see myself using reduce a lot in the future
17:13rosejnWhat's the best way to look at *err* while in the repl?
17:14tomojrosejn: I'm not sure that makes sense
17:14rosejnhmmm, ok
17:14ambient*e
17:14tomojoh, now I get it. been awake too long. :(
17:14ambient?
17:14rosejnI'm trying to use clojure.contrib.logging
17:14ambient(i dont even know what *err* does)
17:15tomojit's STDERR, no?
17:15rosejnIt's just like another standard out, but for errors
17:15ambientok
17:15rosejna pipe you can connect to things
17:15tomojyou mean the slime repl or a plain old repl?
17:15rosejnvimclojure repl
17:16rosejnI've inserted (log :debug "my msg here...") messages, but it seems that clojure.contrib.logging is sending stuff to *err*
17:17rosejnit's also not clear how to set the log-level...
17:17tomojI suppose that's vimclojure's business, not clojure's? (the former)
17:17mgarrissi need a function that returns any repeating pattern in a vector: (foobar [3 4 19 2 4 2 4 2 4 2]) ==> [2 4]
17:17mgarrissor i should say the first repeating pattern found
17:18lisppaste8crios pasted "ternary if" at http://paste.lisp.org/display/88306
17:19criossure do exits a better way than my "ternary if" in http://paste.lisp.org/display/88306
17:19crios*exists
17:19chousercrios: you want :else ?
17:20criosmmm I think so. but can I put an if inside cond?
17:21criosBTW, why (memq 'n '(a b c) ) throw a StackOverflowException?
17:21hiredmancond checks for true values
17:22hiredmannot nil and not false
17:22chousercrios: 'rest' always returns a seq, perhaps an empty one
17:22chouseryou probably want 'next'
17:22hiredman:else is not nil and not false, so it can be used as a catch-all there
17:23technomancyso... it looks like the use-fixtures function is not really intended for interactive development since it keeps wrapping more and more fixture functions around the test functions rather than being idempotent
17:23technomancyI wonder if there's a way to fix that
17:23chouser,(some #{'b} '(a b c))
17:23clojurebotb
17:23crioschouser: mmm ok, I check that
17:23chousercrios: is that what you want?
17:24criosyes :-(
17:24technomancyyou could store the fixtures as a set, but then you lose the ability to order it.
17:25crioschouser: but also studying this: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-16.html , just for "set the stage"
17:25crios[memq example is there, written in Scheme]
17:36lisppaste8crios annotated #88306 "goes in StackOverflow" at http://paste.lisp.org/display/88306#1
17:37criosanother try: I'm using next in this implementation, but I get a StackOverflow
17:38lisppaste8Chouser annotated #88306 "some other versions" at http://paste.lisp.org/display/88306#2
17:40criosthank Chouser; I'll study it. But why :else is not documentated here http://clojure.org/API#toc161 ?
17:41chousercrios: it's just convention -- any true value will do
17:41criosah ok, it is a keyword which evalutes to true, isn't it?
17:41chousercrios: right
17:43criosan other question: in your second example, (recur calls memq itself, right?
17:43chousercrios: yes
17:43chouserbut without cosuming a stack frame, so no stack overflow
17:46criosit seems that the trick is the (when function:
17:47chouser(when x y z) is just (if x (do y z))
17:47lisppaste8crios annotated #88306 "untitled" at http://paste.lisp.org/display/88306#3
17:48criosI mean, that last implemention doesn't go in StackOverflow
17:48crios(thought your is sure better)
17:49crios*though
17:52chouser(next x) returns nil when x has zero or 1 items left. nil acts as false so we stop looping
17:52chousergotta go.
17:57criosso here http://paste.lisp.org/display/88306#1 memq is infinitely called with arguments (item nil) ?
17:58criosUsing when, the recursive call with (item nil) is not tried
17:58criosI think it makes sense
18:08MetaReillyAre there current instructions for setting up slime and swank manually (NOT using clojure-install)?
18:09spaceman_stuis there a way to iterate over a transient vector? something like (doseq [i (transient [1 2])] i)?
18:09technomancyspaceman_stu: I don't know if you're supposed to use transients while they're still transient
18:10mgarrisslet's say i wanted to use clojure to draw a fractal. is the AWT my best bet here for the actual displaying?
18:10technomancymgarriss: clj-processing is probably the easiest
18:10spaceman_stutechnomancy: get and nth work. Those are along the same lines, no?
18:11hiredmanspaceman_stu: you would need to use some kind o reduce operation
18:11hiredmanof
18:11spaceman_stuI don't understand why
18:12mgarrissMetaReilly: here is the clojure section of my .emacs, i just started using clojure so it probably has issues but it might help you: http://pastie.org/644604
18:13MetaReillymgarriss: thanks
18:13hiredmanspaceman_stu: because you are supposed to keep the result of the transient mutation operations
18:13MetaReillymgarriss: i was using the old slime/swank setup from before the new automated install and find the automated setup annoying
18:13mgarrissMetaReilly: you'll have to build the swank-clojure jar using maven first
18:14mgarrissMetaReilly: me too
18:14MetaReillymgarriss: Thanks
18:14technomancyMetaReilly: you could read the source to clojure-install. =)
18:15MetaReillytechnomancy: I had started to do that and decided that it would be worth asking if somebody had a recipe handy
18:15hiredmanclojurebot: transient is <reply> Don't bash in place
18:15clojurebot'Sea, mhuise.
18:20mgarrisstechnomancy: clj-processing looks perfect, thx for the lead
18:20clojurebottechnomancy is to blame for all failures
18:21hiredman~laugh
18:21clojurebotha ha
18:21technomancyclojurebot: maybe so, but hiredman is to blame for all errors
18:21clojurebot'Sea, mhuise.
18:21technomancywait, did that just do what I think it did?
18:21technomancyclojurebot: hiredman?
18:21clojurebothiredman is lazy
18:22technomancyclojurebot: maybe so, but hiredman?
18:22clojurebotmaybe so, but hiredman is to blame for all errors
18:22technomancyclojurebot: forget maybe so, but hiredman
18:22clojurebotI forgot maybe so, but hiredman
20:43herdrick_l
20:49enderoutehow do you set a breakpoint in jswat for a running clojure repl? I see all my functions in the "classes" list to the left, i right click and add a breakpoint, but it doesn't seem to stop when i call the function from the repl
23:32jaiganeshhi
23:32jaiganeshi have a problem
23:33jaiganeshi am trying to use lcm function but getting this error
23:33jaiganeshjava.lang.Exception: Unable to resolve symbol: lcm
23:33jaiganeshi have use clojure.contrib.math dont hsi
23:34jaiganeshi have included the namespace "use clojure.contrib.math"
23:36jaiganeshanyone?
23:37jaiganeshhi room
23:37jaiganeshi have aproblem
23:37jaiganeshi am trying to use lcm function but getting this error
23:37jaiganesh java.lang.Exception: Unable to resolve symbol: lcm
23:37jaiganeshi have included the namespace "use clojure.contrib.math"
23:43jaiganeshhi room
23:48adityohey
23:54rongenreLooking for an idiom: I have a bunch of vectors, all equal length. Want to treat them like a table, search, select based upon it. Like in R with dataframes
23:57arbscht,(doc filter)
23:57clojurebot"([pred coll]); "
23:58rongenrewell sure. I can filter one vector
23:58arbscht,(filter (comp odd? first) [[1 2 3] [4 5 6] [7 8 9] [10 11 12] [13 14 15]])
23:58clojurebot([1 2 3] [7 8 9] [13 14 15])
23:58rongenreBut I want to use it to index the rest.
23:59somniumrogenre: something like (filter identity (map #(filter pred vec) bunch-of-vecs)) ?
23:59rongenreso it'd take that to [1 3] [4 6] [7 9] [...]