#clojure logs

2009-05-14

03:01cadshey, how should I implement a multimap where multiple values may act as a key for one map entry?
03:03cadsoh, that's just a normal map with value duplication :D
03:10fffejdoes gen-class allow you to annotate methods with java Annotations?
03:10fffej(I couldn't see anything in the docs)
03:15replacafffej: I don't believe so
03:16fffejthanks!
03:20tWipthat would be good, for example creating ejb3 entity classes
03:22markusgustavssonSomething better would be to not have to create EJBs at all :) a boy can dream...
03:22replacayeah, Rich has decided that he doesnt want gen-class to go all the way to all the functionality of java classes and is thinking about the best approach to that
04:16cadsin the commandline repl, is there any way to make it interpret ctrl-c as abort-eval instead of exit?
05:41unlinkIs there any way to determine if a script is being run directly or imported?
05:49AWizzArdscript = Clojure program?
05:50unlinkclojure asdf.clj vs clojure -e "(use 'asdf)"
05:52AWizzArdmaybe in the args of the main method?
05:52AWizzArdyou could see if you can find "-e"
05:55unlinkWhat main method?
06:02AWizzArdOf the class
06:02unlinkfwiw clojure parses out everything before and including the script name
06:02unlinkI'm not sure what class you're talking about
06:03AWizzArddid you say "clojure asdf.clj" short for a call to "java -cp clojure.jar ..."
06:03AWizzArd?
06:06unlinkyes, java -cp clojure.jar clojure.main asdf.clj
06:11AWizzArdthe idea is that you don't call clojure.main
06:11AWizzArdbut instead your own main
06:11AWizzArdand to that you can pass arguments, such as -e
06:11AWizzArdthen the basic idea is: if your main method was not called, then your program was not called directly
06:12AWizzArd(defn -main [args] ...)
06:12AWizzArdand put a (:gen-class) into your (ns)
06:14unlinkAWizzArd: But this requires AOT compilation, right?
06:14AWizzArdyes
06:15AWizzArdI guess
06:15AWizzArdwell, don't know actually
06:20achim_punlink: something similar was dicussed on the google group: http://groups.google.com/group/clojure/browse_thread/thread/ca60d98fb4f7e71e/16b0ebb277daf5b9
06:26unlinkthanks
06:27unlinkI'm getting a 500 from google, heh.
06:56djpowellIs there a guide anywhere on how to call Clojure dynamically from Java? I guess that is a question that a few people will ask.
06:56djpowellclojurebot: paste
06:56clojurebotlisppaste8, url
06:56lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
06:57lisppaste8djpowell pasted "Calling clojure dynamically?" at http://paste.lisp.org/display/80198
07:31rhickeydjpowell: RT.var is the best way to get a handle on vars. Then use it for all interop that you can, i.e. you can get the var for require or use and use them to load code
07:33rhickeydjpowell: http://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/main.java?spec=svn1368&r=1368
08:09jdzdjpowell: i have not tested, but with gen-class you can create classes that behave just like ordinary Java classes
08:35AWizzArd,(ref 0)
08:35clojurebot#<Ref@c707c1: 0>
08:36AWizzArdThe is the c707c1 in that output guaranteed to be unique in that jvm?
08:36yasonclear
08:37AWizzArdif it is for example the address in ram then it could not change, but if it is some hash code that gets calculated...
08:38AWizzArd,(let [r (ref 0)] [r (format "%x" (System/identityHashCode r))])
08:38clojurebot[#<Ref@13d422d: 0> "13d422d"]
08:48bstephensonI run (ref 0) twice in a row in my REPL and get back two different Ref@ numbers
08:48dnolenyou created two refs
08:48bstephensonahh
08:49dnolen,(ref 0)
08:49clojurebot#<Ref@1fcbac1: 0>
08:49dnolen,(ref 0)
08:49clojurebot#<Ref@b0ede6: 0>
08:50bstephenson(def x (ref 0))
08:50bstephenson,(def x (ref 0))
08:50clojurebotDENIED
08:50dnolenyeah you can't def clojurebot.
08:50AWizzArd,(let [x (ref 0)] (println x))
08:50bstephensonwell, if that was allowed by clojurebot, when you see the ref for x, it is the same every time
08:51dnolen,(let [refA (ref 0) refB (ref 0)] (= refA ref B))
08:51clojurebotjava.lang.Exception: Unable to resolve symbol: B in this context
08:51dnolen,(let [refA (ref 0) refB (ref 0)] [(= refA refB) (= refA refA)])
08:51clojurebot[false true]
08:52AWizzArdThe thing is: is the hash code of that ref unique for the running session?
08:53AWizzArdwell, probably not for the running session
08:54AWizzArdbut I hope at least for any two refs that currently still live that hash code will be pairwise different
08:54jdzif that is a hash code then why should it be different?
08:54jdzi mean, necessarily different?
08:55rhickeyAWizzArd: no guarantee that hash codes will be different, by definition they are not identities
08:56AWizzArdjdz: yes, that was what I said about 1,5 minutes before you entered ;)
08:57AWizzArdSo, (let [a (ref 0), b (ref 1)] (= (System/identityHashCode a) (System/identityHashCode b))) ==> true is possible.
08:58rhickeyhttp://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#identityHashCode(java.lang.Object)
08:58rhickeymakes few promises
09:00AWizzArdright
09:19yasonuh, I'm failing to find a simple membership test function for sequences, such as "x in seq" (Python), "indexOf" (JS), etc.
09:19dnolen,(.indexOf 'a ['a 'b 'c])
09:19clojurebotjava.lang.IllegalArgumentException: No matching method found: indexOf for class clojure.lang.Symbol
09:20dnolenoops
09:20dnolen,(.indexOf ['a 'b 'c] 'a)
09:20clojurebot0
09:20dnolen,(.indexOf 'c ['a 'b 'c])
09:20clojurebotjava.lang.IllegalArgumentException: No matching method found: indexOf for class clojure.lang.Symbol
09:20dnolen,(.indexOf ['a 'b 'c] 'c)
09:20clojurebot2
09:21dnolen,(some #{'y} ['x 'y 'z])
09:21clojureboty
09:21yasonok so java it is -- is that efficient?
09:21dnolenif you just want to test membership
09:21dnolenyes.
09:21yasonplain membership test is fine, akin to "x in seq" in Python
09:22yasonthe set thing with (some) is ugly though :)
09:22dnolenthen use some.
09:22yasonI'm surprised there isn't a built-in like (member?) or something
09:23dnolenheh, it's idiomatic. and more general
09:23dnolen,(some #{'a 'b} ['x 'y 'b])
09:23clojurebotb
09:24yasonYeah but it's ugly, you have to know and recognize the pattern.
09:24yasonBy the way .indexOf doesn't work for lazy sequences
09:24dnolenjust as you have to recognize list comprehension for Python. to each his own ;)
09:25yasondnolen: well, the latter works for lazy seqs too so I consider it a better fit
09:25yasonI've used the (some #{...} ) before but it always felt like a hack :)
09:26yasonbut hey, thanks anyway for validation
09:28dnolenno prob. you could always add your own fn, (defn in? [coll x] (some #{x} coll))
09:35jdz_,(contains? [1 2 3] 3)
09:35clojurebotfalse
09:35jdz_,(contains? '(a b c) 'c)
09:35clojurebotfalse
09:35durka42man, dev.java.net is really slow
09:35dnolen(,doc contains)
09:35dnolen,(doc contains)
09:35clojurebotjava.lang.Exception: Unable to resolve var: contains in this context
09:36dnolen,(doc contains?)
09:36clojurebot"([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."
09:36jdz_oh, that's not for sequences
09:36durka42and not for values
09:36jdz_what do you mean not for values?
09:38jdz_,(some (partial = 'c) '(a b c))
09:38clojurebottrue
09:41Chousuke,(some #{'c} '(a b c)) ; this is a fun trick
09:41clojurebotc
09:41jdz_it kinda feels wrong to me when testing for only one value...
09:41ChousukeI guess so.
09:42Chousukebut it's a clojure idiom.
10:02durka42clojurebot: paste?
10:02clojurebotlisppaste8, url
10:02lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
10:06durka42trying to using Chouser's JNA to prove Charles Nutter wrong:
10:06lisppaste8durka42 pasted "vim" at http://paste.lisp.org/display/80211
10:27drewrIs there an idiomatic way to capture exceptions from an Executor?
10:33jdzWhat's Executor and how its exceptions are different from any other exceptions?
10:37drewrjdz: It's an abstraction for spawning command executing in threads.
10:38drewrNormally I would use an agent and its facilities for tracking down exceptions, but in this case I have an await in the code that gets spawned.
10:42drewrs/executing/execution/ ^^~2
10:43drewrI don't know the Java ways of dealing with that, but I'
10:43drewrm assuming it's the same in clojure.
10:45jdzi must admit i don't see what's the problem without any code
10:46tWipwhy not have the Runnable implementation store it in a field and access it?
10:47drewrtWip: Yes, I considered that.
10:48drewrAlso, JCIP mentions UncaughtExceptionHandler.
10:48tWipwhy do you need to "capture" exceptions? why can't the runnables just catch them and do the appropriate thing
10:49tWipor have them notify some other code about them
10:51drewrtWip: Sounds good. Just wanted to make sure there wasn't something more pre-fab.
10:51tWipit's of course a design decision on where you want to react to problems
10:53drewrThe convenience of agent-errors threw me off. :-)
11:11liwpdoes anyone here have any idea how to evaluate a form in slime in the current namespace rather than in 'user?
11:12stuartsierraIt should happen automatically if your source file has a (ns...) at the top.
11:12liwpMy problem is that when I send a form to slime with C-x C-e, it gets evaluated in 'user rather than in the namespace of the source file. And therefore my other code keeps using the old definition according to the namespace rather than the new definition.
11:12liwpstuartsierra: I've got the (ns ...) in the source file
11:12dnolenliwp: you need to evaluate the ns statement first.
11:12liwpI've change the namespace in the repl with (in-ns ...)
11:13liwpdnolen: I've compile the whole buffer with C-c C-k before...
11:13stuartsierraTry C-M-X instead of C-x C-e.
11:13stuartsierraC-M-x I mean
11:14liwpstuartsierra: Ok, I'll give it a try when I get home
11:14dnolennot sure C-c C-k keeps things in sync.
11:15dnolenwhen I'm in the REPL zone, I usually select all the working code and do C-c C-r to evaluate the region.
11:15liwpI'll just have to figure out the correct workflow for myself...
11:15dnolenthen I use C-x C-e and C-M-x
11:15liwpdnolen: and that works fine with namespaces?
11:16dnolenit does for me, yes.
11:16dnolenswank-clojure matches the buffer to a ns if you C-x C-e a name space definition.
11:16liwpdnolen: I haven't C-x C-e'd the namespace so maybe that's the problem
11:17liwpI guess compiling the file isn't enough for swank-clojure
11:17liwpthanks guys
11:17markusgustavssonC-c C-k followed by C-x C-e on single forms works fine for me
11:17liwpmarkusgustavsson: even with namespaces?
11:17markusgustavssonyeah
11:17markusgustavssonAt least I think so.. can check to make sure :)
11:17liwpmarkusgustavsson: is your repl in 'user or in the other namespace?
11:18markusgustavssonit's in user, does not affect C-x C-e
11:19dnolenok, I can confirm that markus is correct.
11:19liwpmarkusgustavsson: mine's not in 'user so I thought that might have something to do with it not working, but seems a bit weird
11:19dnolenliwp I take that back.
11:20dnolenC-c C-k doesn't synchronize the file to an ns in the proper way.
11:20liwpdnolen: so it's broken for you too?
11:20dnolenyup
11:20dnolenthat's why I don't bother with it when doing stuff in the REPL.
11:20dnolenonly when sanity checking a file.
11:20liwpI haven't updated my slime/swank-clojure for a while so it might be that it's been fixed
11:21markusgustavssonliwp: just tried C-c C-k followed by C-x C-e on an additional defn and the new function gets added to the correct namespace - the one specified in my buffer - regardless of the ns in the repl.
11:21markusgustavssonBut I don't have the latest svn versions of everything
11:21liwpdnolen: makes sense - I guess I need to figure out another work flow for myself, which is fine, C-c C-k just seemed like a simple way to load the file to clojure before making changes
11:22liwpmarkusgustavsson: good for you ;-)
11:22stuartsierraI use slime-eval-buffer
11:22dnolenok, I just updated slime.
11:22dnolenseems to work when everything is up to date.
11:22liwpstuartsierra: what't that bound to by default?
11:23stuartsierranothing
11:23liwpdnolen: ahh, I'll need to update then
11:23liwpstuartsierra: I thought so, that's why I'm not using it. I might as well replace C-c C-k with it. Do you have it bound>
11:23stuartsierrano
11:25liwpthanks everyone
11:31stuartsierraRe the JSON "NULL" thing from yesterday -- even Firefox won't parse it.
11:32danlarkinwhere do they think they get off sending "NULL"... the nerve... :-o
11:32stuartsierra:)
11:38danlarkinthat was kindof serious though, maybe I shouldn't patch to allow NULL
11:42stuartsierraI'm disinclined to do support it.
12:19stuartsierraAnyone else having trouble connecting to Google sites?
12:20unlinkNeither of the methods described in http://groups.google.com/group/clojure/browse_thread/thread/ca60d98fb4f7e71e/16b0ebb277daf5b9 work for detecting whether a script has been invoked directly or (use)'d.
12:20unlinkThat is, neither *ns* nor *command-line-args* depend on this.
12:21danlarkinstuartsierra: I am not, but I've seen a few people on the twitter and some remote coworkers are
12:22stuartsierraunlink: I think the recommended procedure now is to define a main function and invoke it.
12:22stuartsierradanlarkin: thanks
12:22unlinkstuartsierra: Invoke it where?
12:23stuartsierraOn the command line.
12:23unlinkstuartsierra: You mean with AOT compilation?
12:24stuartsierraunlink: not necessarily, although AOT permits you to run "java -cp ... your.class.name"
12:24unlinkstuartsierra: Right, but I don't see how you could invoke a clojure method from the command line without AOT.
12:25unlink(or something silly like -e (use 'com.example.test) (-main))
12:25stuartsierraThat's basically it. You can use the "-i" option to load the file, then "-e" to run it.
12:26unlinkThat seems like it's screaming for a language feature.
12:27stuartsierraStephen G. suggested adding metadata to the namespace to identify a "main" function. I suggested always using "-main".
12:27unlinkAlternatively a *name* binding could be used (borrowing from Python, ruby et al)
12:29unlinkI would be fine with either a special "main" name or annotation or a binding for the script being invoked.
12:47stuartsierraunlink: another option is to have a separate "driver" .clj script that just calls your main function.
12:47unlinkright
12:48unlinkPython and Ruby users will expect the feature I'm looking for, and I think it's simply a good idea anyhow (for rapid development and for single-module projects).
12:48stuartsierrayes
12:53ieureAgreed, I was just looking for something like Python's if __name__ == '__main__' trick.
12:54replacaieure: this comes up all the time and we need to come up with a nice way to do that. It shouldn't be hard to come up with a way that's nicer than python's!
12:55technomancyreplaca: agreed; that trick is clunky as the dickens.
12:55unlink"idiom" :-)
12:55replacatechnomancy: but I use it all the time and I feel the lack of it in Clojure
12:56stuartsierraShort answer: use AOT-compilation for now, suggest new feature.
12:56replacathat's right
12:57technomancyCLI launching methods have always been a weak point of clojure.
12:57replacastuartsierra: did you see my comment yesterday about json.write vs. clojure-json performance?
12:57unlinkWhich brings up the related point that AOT compilation could be simplified.
12:57stuartsierrareplaca: no
12:58replacaI ran a benchmark (cause I was testing pretty print dispatch) and simple json output was ~20x faster in clojure-json than in json.write.
12:58replacaI was testing with my API index from the contrib autodoc
12:58stuartsierraWhich contrib SVN did you have?
12:59replacawithin the last few, don't know exactly
12:59stuartsierraok
12:59replacaI'm always up to date within a few days
12:59replacadunno if there's something unusual about my case.
13:00stuartsierraI'll try it
13:00replacait's almost 300K at the end
13:02replacastuartsierra: yeah, you can grab some JSON from http://clojure-contrib.googlecode.com/svn/wiki/ApiDocIndex.json
13:02stuartsierraI've got tons.
13:02replacastuartsierra: cool
13:15stuartsierraHmm. c.c.json.read appears to be just slightly faster.
13:20stuartsierraTesting c.c.json.write now
13:23stuartsierrac.c.json.write is much slower, around 20:1.
13:24stuartsierraIt's probably the multimethods & derive.
13:24danlarkincombine forces!
13:24stuartsierraok
13:24danlarkinstuartsierra: yeah I tested clojure-json's encoder with multimethods instead of cond... slowed it down so I took them out
13:29stuartsierraSigh... elegance is always the first to fall.
13:31hlshipIf I have a symbol, say 'foo, how do I get the namespace for it? Context: want to write utilities to load resources from the classpath, relative to the symbol's namespace.
13:32danlarkin(doc namespace)
13:32clojurebot"([x]); Returns the namespace String of a symbol or keyword, or nil if not present."
13:33hlshipuser=> (foo 1)
13:33hlship2
13:33hlshipuser=> (namespace 'foo)
13:33hlshipnil
13:33hlshipSo foo exists, but (namespace 'foo) returns nil, that's why I'm confused.
13:34hlshipAnd (ns-resolve) seems to require the namespace in the first place.
13:35jkantzwhat's the fastest way to do a > comparison on integers?
13:35jkantzI don't see any unchecked options for that
13:35danlarkinhlship: you're passing 'foo to the namespace function
13:35danlarkinhlship: 'foo has no namespace
13:35danlarkinhlship: 'user/foo does, however
13:36danlarkinjkantz: unchecked- functions are no faster than the checked variants
13:36danlarkin> will be suitably fast
13:36danlarkinno faster, that is, within a margin of error
13:37danlarkinlisppaste8: url
13:37lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
13:37stuartsierraHuh. Eliminating multimethods didn't make that much difference.
13:37hlshipI want to be able to say (find-classpath-resource 'foo "style.css") and find /my/namespace/for/foo/style.css on the classpath
13:37lisppaste8danlarkin pasted "resolve*" at http://paste.lisp.org/display/80228
13:38danlarkinhlship: does resolve* help?
13:38hlshiplet me see ...
13:39danlarkinoh, no, resolve* is for resolving functions, not resources
13:40jkantzdanlarkin, is that because the jit will eventually make the needed optimizations?
13:40hlshipuser=> (resolve 'foo)
13:40hlship#'user/foo
13:40hlshipuser=> (namespace (resolve 'foo))
13:40hlshipjava.lang.ClassCastException: clojure.lang.Var (NO_SOURCE_FILE:0)
13:40hlshipuser=> (ns-resolve *ns* (resolve 'foo))
13:40hlshipjava.lang.ClassCastException: clojure.lang.Var (NO_SOURCE_FILE:0)
13:40hlshipuser=> (namespace (resolve 'foo))
13:40hlshipjava.lang.ClassCastException: clojure.lang.Var (NO_SOURCE_FILE:0)
13:40hlshipuser=>
13:41danlarkinjkantz: yes. Also you can cast your variables with (int ...)
13:41danlarkininside function-boundaries they'll stay primitive ints
13:41hlshipWorse, in my tests (running from La Clojure in REPL), *ns* appears to be "user" regardless, which is odd
13:41danlarkinhlship: resolve returns a var, not a symbol
13:42stuartsierraReflection makes a big difference, though.
13:43hlshipRight, that's why I'm struggling.
13:43hlshipIn Java, I could just getClass().getClassLoader().getResource()
13:44danlarkinhlship: how about (:ns (meta (resolve 'foo)))
13:45hlship(one minute ...)
13:53danlarkinstuartsierra: how much faster is it with the hints?
13:54stuartsierraReading is slightly faster, now I'm getting 2x faster than clojure-json. Writing is MUCH faster, but still about 2x slower than clojure-json.
13:54stuartsierraStill experimenting.
13:55danlarkinI spent time optimizing encoding in clojure-json, but not much optimizing decoding, I guess it shows
13:56stuartsierraok
13:56stuartsierraIt might be the difference between building a String and calling (print...)
14:03hlship(:ns (meta (resolve 'foo))) thanks! Should help.
14:04replacastuartsierra, danlarkin: looks like the competitive free market is working!
14:04stuartsierra:)
14:04hlshipnow if there was only the concept of "this" for functions or namespaces
14:05danlarkinhlship: *ns*
14:05replacastuartsierra: I did pretty printing versions of c.c.json.write and c.c.prxml in c.c.pprint.examples
14:05kotarakhlship: (fn this [] ....)
14:05hlshipThat was my first try, and (perhaps due to test-is), was coming up as "user"
14:05ieureWhat kind of Clojure benchmarking tools are there?
14:06replacaieure: (time), -hprof, stuart put some profiling into contrib
14:07stuartsierraexperimental...
14:07replacaieure: those are the ones I think of off the top of mmy head
14:07lisppaste8hlship pasted "find-classpath-resource" at http://paste.lisp.org/display/80231
14:08hlshipSo (:ns (resolve 'foo)) works in REPL
14:09hlshipah ... so my problem, oops
14:09kotarakhlship: you have to replace - with _ also. Not only . with /.
14:10ieureHmm. So I'm not sure if I'm doing something wrong, but this SQL query I'm running is OOMing the JVM. Seems like (with-query-results) buffers the whole (large) resultset.
14:11ieureI'm doing (with-query-results rs ["SELECT gobs_of_rows;"] (map (fn [row] ...)))
14:12hiredmanat the repl?
14:12ieureYes.
14:12lisppaste8hlship annotated #80231 "final version w/ test" at http://paste.lisp.org/display/80231#1
14:13hlshipthanks for the help
14:13hiredmanieure: the repl is try to realize the map to print out the result
14:13hlshipusing the (meta) was a cool trick
14:13ieurehiredman, Hm, okay.
14:14kotarakieure: maybe you can try (doseq [row (with----)] (println row)).
14:14kotarakThis should not hold on the head of the sequence
14:15hlshipanybody doing web apps w/ clojure currently?
14:15technomancyhiredman: that needs to be a clojurebot faq like how he says map is *LAZY*
14:15technomancy,repl
14:15clojurebotjava.lang.Exception: Unable to resolve symbol: repl in this context
14:15technomancyclojurebot: repl?
14:15clojurebotwhose job is<reply>that is triddells job
14:15dnolenhlship: I've been using compojure to rapid prototype front ends, as well as playing around with GAE.
14:15hiredman,clojure.main/repl
14:15clojurebot#<main$repl__5796 clojure.main$repl__5796@1342f5b>
14:16kotarakclojurebot: the repl is also holding onto the head of sequences when printing them.
14:16clojurebotYou don't have to tell me twice.
14:16kotarakclojurebot: repl
14:16clojurebotthe world <reply>what the world needs is more higher order functions
14:16kotarakclojurebot: the repl
14:16clojurebotthe repl is holding onto the head of sequences when printing them.
14:16hiredmanclojurebot: whose job is it to make you talk to twitter correctly
14:16clojurebotAlles klar
14:16hiredmaner
14:16hiredmanwhoops
14:16hlshipI'm taking a breather from Tapestry and trying to build a Clojure web framework using Tapestry-style templates
14:16hlshipbut it will be action oriented, not component oriented
14:17nurey_machlship: looks nice, please no struts alike if you can :-)
14:17hlshiphoping to make it highly parallel as well
14:17hiredmanclojurebot: literal whose job
14:17clojurebotwhose job is it to make you talk to twitter correctly
14:17hiredmanclojurebot: forget whose job
14:17clojurebotI forgot whose job
14:17hlshipnope; maybe more like Stripes perhaps
14:17hlshipbut with T5 templates
14:17hlshipcoming together nicely
14:17hiredman~whose job is <reply>that is #someone's job
14:17clojurebotRoger.
14:18hiredmanclojurebot: whose job is it to make you talk to twitter correctly?
14:18clojurebotIk begrijp
14:18hiredmanbah
14:18hlshipup on GitHub: http://wiki.github.com/hlship/cascade
14:18hiredmanclojurebot: whose job would it be to make you talk to twitter correctly?
14:18clojurebotthat is kotarak's job
14:19hlship#tapestry
14:19hlship(oops)
14:20nurey_machlship: it cascade was out and 2 years mature, I would have tried to recommend it. I'm not having fun with rails,grails jsp style templates :-(
14:22dnolennurey_mac: have you looked Enlive? I have a distaste for mixing code and markup. Enlive solves that particularly problem nicely.
14:22technomancyenlive is awesome
14:22nurey_macthanks guys, I'll read about it
14:23stuartsierra:-Dc.c.json.write is now a little faster than clojure-json
14:23stuartsierraYou have to call it a few thousand times to see the effects, though.
14:24danlarkinstuartsierra: sweet, now just clean up that ugly api :)
14:25replacastuartsierra: did you get that big cond out of there? A table would speed things up
14:25stuartsierraNo more conds.
14:25technomancystuartsierra: thoughts on using keywords as map keys instead of strings?
14:25replacastuartsierra: yay!
14:25stuartsierratechnomancy: Use c.c.walk/keywordize-keys
14:26stuartsierrareplaca: ok, one small cond, but mostly multimethods
14:35stuartsierratechnomancy: ok, you talked me into it. Bind *json-keyword-keys* to true.
14:36technomancystuartsierra: nice! =)
14:37technomancystuartsierra: it's weird since JS treats object keys as strings, but when you use dot notation it suggests keywords/symbols
14:37clojurebothttp://clojure.org/data_structures#toc8
14:37stuartsierraI'm reluctant to do that, b/c there's no way to verify that a string makes a valid keyword.
14:37technomancystuartsierra: oh! I have a patch for that
14:37stuartsierraWhat if the string is something like "foo/bar"? Do you get a namespaced keyword?
14:38technomancyclojurebot: issue #13
14:38clojurebotTitim gan �ir� ort.
14:38technomancyhiredman: he should get hooked up to google code. =)
14:38technomancyhttp://code.google.com/p/clojure/issues/detail?id=13&amp;colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary
14:38technomancyhiredman: is there any way to get templated clojurebot replies?
14:39technomancysomething like clojurebot: issue (\d) is<reply>http://code.google.com/p/clojure/issues/detail?id=\1
14:39danlarkinI don't like this issue :) I like being able to create symbols/keywords that aren't readable
14:40technomancydanlarkin: sure; just use (. clojure.lang.Symbol (intern ns name))
14:40technomancybut you need to know what you're doing
14:40danlarkintechnomancy: oh yes, that's just as convenient as 'foo :)
14:41stuartsierrahttp://clojure.org/todo mentions "arbitrary symbols in | |" but Rich has wavered on this.
14:46replacastuartsierra: I sometimes wonder if multimethods are just a fancy syntax for cond :-)
14:48cemerickreplaca: *everything* is just a fancy syntax for cond ;-)
14:50twismagrees with danlarkin that *json-keyword-keys* default should be true
14:51twismbut stu brings up a good point about "foo/bar" json keys
14:56stuartsierraAlso, I don't want to change the API if I can help it.
15:00technomancywell contrib isn't 1.0 yet... so if you're going to change the API, now's the time. =)
15:01stuartsierrayeah, I'll think about it.
15:01danlarkinat least make it consistent :)
15:01stuartsierraconsistent?
15:02danlarkinwell there's read-json-string to read and then json-str to write
15:03stuartsierraThat follows read-string and str in Clojure.
15:03danlarkinit's gross :-o
15:03stuartsierrayes
15:12stuartsierraok, now read-json takes a string too.
15:13stuartsierraThat leaves read-json, print-json, and json-str.
15:13danlarkinread-json and write-json? pretty please
15:13danlarkinmmm
15:14stuartsierraprint-, not write-, because it prints to *out*
15:15danlarkin:)
15:18stuartsierraSo I guess it should be called c.c.json.print, but whatever.
15:21metasyntax|workIf I do (ns foo.bar.Test (:gen-class)) and then (compile 'foo.bar.Test) I get a java.io.IOException: No such file or directory (Test.clj:1)
15:22metasyntax|workRunning `java -cp ... clojure.main` from a directory such that it has children foo/bar/Test.clj beneath it.
15:24hoeckmetasyntax|work: bind *compile-path* to a dir where the compiled classes should go
15:25hoeckmetasyntax|work: like (binding [*compile-path* "."] (compile 'foo.bar.Test))
15:25hoeckmetasyntax|work: where "." must be on the classpath
15:26metasyntax|workAh, I see. I think the IOException was because *compile-path* didn't exist.
15:26metasyntax|workSo *compile-path* must both exist and be in the CLASSPATH for compile to work it seems.
15:27hoeckmetasyntax|work: it's bound to "classes", but the "./classes" dir is probably not in your classpath
15:27hoeckmetasyntax|work: so it compiles the namespace but fails to load it after compiling
15:27metasyntax|workhoeck: That was a second-step problem, first I had to make the "classes" directory.
15:27metasyntax|workhoeck: But you're right, thank you.
15:28hoeckmetasyntax|work: np :)
15:43durka42cool, they're getting ready to ship the book :)
15:53twismhow would you set *json-keyword-keys*
15:53twism?
15:53stuartsierrabinding or alter-var-root
15:53twismwithout (bind [*json-keyword-keys* ....
15:53twismah
15:53twismwhat happened to set!
15:54stuartsierraset! won't change root bindings
15:55twismoh i just couldnt find set! in the api
15:55twismon the website
15:55twism,(doc set!)
15:55clojurebotjava.lang.Exception: Unable to resolve var: set! in this context
15:55stuartsierrahttp://clojure.org/java_interop#set
15:56twismthats my bad...
15:56twismset! is java interop
15:56stuartsierrano prob
15:56stuartsierraNot exactly, it's a special form. It works on thread-bound vars.
15:59twism*meant <twism> without (binding [*json-keyword-keys* ....
15:59twismjust correcting
16:02metasyntax|workWith gen-class, how do I specify a static method?
16:03metasyntax|workI tried putting #^{:static true} into the metadata of the function but Java still claims it's non-static.
16:04metasyntax|workSomething like (defn -test #^{:static true} ([x y] (+ x y))).
16:04mattreplmetasyntax|work: are you putting it in the function definition or the function signature
16:04mattreplit needs to go in the signature
16:06metasyntax|workmattrepl: where do I put it there? in the parameter list?
16:07mattreplat the the start, the #^ will attach the metadata to the next object, which will be the signature of the function you want to be static
16:07metasyntax|workmattrepl: OK, I see. Thanks!
16:08mattrepl=)
16:09twismstuartsierra: sorry about my ignorance... but what am i doing wrong here
16:09twism(alter-var-root clojure.contrib.json.read/*json-keyword-keys* (fn [] true))
16:09metasyntax|workFirst time using Clojure here, it's very cool. The closer I can get to Scheme while still doing work the better.
16:14stuhoodtwism: the function needs to take the current state as an argument
16:15stuhoodtwism: try: (alter-var-root clojure.contrib.json.read/*json-keyword-keys* (fn [_] true))
16:15triddell\
16:17stuartsierrayes
16:17stuartsierra(alter-var-root #^clojure.contrib.json.read/*json-keyword-keys* (fn [_] true))
16:18stuartsierraOr wrap read-json in your own function with a binding.
16:19twismthanks
16:24kotarakDid anyone encounter trouble with the latest clojure revisions? /Users/mb/Documents/Projects/Clojure/vimclojure/build.xml:66: java.lang.NoClassDefFoundError: clojure/core$this__4984__auto____4601 (util.clj:23)
16:24kotarakLine 23 is the ns clause of the file.
16:25twismloves when all the tests pass
16:26twismthanks stuhood and stuartsierra
16:29Chousukekotarak: you sure you have everything properly compiled? :)
16:30kotarakChousuke: I thought so, but it seems the jar is incomplete...
16:31kotarakwhich is funny because the ant target uses <fileset dir="${classes.dir}" includes="**/*"/>
16:33kotarakHmm.. I think, I'm annoyed by the recent changes to the ns makro. :(
16:36unlinkkotarak: what changes
16:36kotarakThe ns makro now creates an anonymous function, which blows up for me for some reason.
16:41kotarakObviously the ns makro generates .class files which somehow vanish on my system. At least the code references this__ classes like the above, which do not exist.
16:42Chousukekotarak: 1367 introduces the class you're missing.
16:42kotarakI'm using 1368 and the class names change...
16:43ChousukeI mean, it introduces the change that breaks clojure for you
16:43kotarakThey come from the anonymous this# function in the ns makro. Which obviously generates an anonymous function per namespace.
16:43kotarakChousuke: yes. The change breaks things.
16:44Chousukesince it introduces an autogensym "this#" inside an anonymous function, which is what you seem to be missing.
16:44Chousukemight be a clojure bug :p
16:44kotarakI'm not really missing it: there are several of this core$this... functions. But not those needed, it seems.
16:44Chousukeyeah, so maybe the compiler is getting confused by it :/
16:48mattrepldo a find for the ones it's looking for, maybe they're getting written somewhere else?
16:51kotarakOk. I found the class, and I know why it's not included in the jar.
16:53kotarakRich really makes it hard to split contrib into smaller jars. :(
16:57stuartsierraDidn't someone successfully split contrib into small jars using maven?
16:58kotarakI did using Ivy. But the anonymous this# doesn't allow to assign them to the correct jar.
16:58stuartsierraah
16:59kotarakI have to make a general ns-jar which contains all this_bla .classes. :(
17:00kotarakProxy is although such an annoyance. :(
17:00kotaraks/although/also/
17:07unlinkIs there any reason the type annotation reader macro #^ doesn't understand primitive types?
17:08stuartsierraunlink: dunno, but you can use the int/byte/short/... functions to the same effect.
17:08unlinkright
17:08kotarakI think for primitives the way is (let [x (int i)] ...)
17:08unlinkIt just seems silly to have 2 parallel idioms
17:08stuhoodagreed.
17:10kotarako.O clojure.core/types$...? Oh dear.... -.-
17:15Chousukeunlink: #^Foo x is a type hint; (foo x) is a coercion
17:16unlinkChousuke: What semantic difference are you trying to express?
17:16unlinkAFAIK to the application programmer they are the same except they operate on different types.
17:16Chousuke(int x) makes x a native int; normally it's of the class Integer (you'd type it as #^Integer)
17:17unlinkand therefore...?
17:17Chousukeif you just did #^int x, it'd be wrong, since x would actually be Integer
17:18Chousukewithout the (int x) coercion that is
17:18unlinkWhich is counter-intuitive. I'm suggesting that #^int be changed to mean something like (let [i (int i)] ...)
17:19Chousukeer, but that's what it is already.
17:19Chousuke#^int doesn't exist :p
17:20ChousukeI suppose there's some mismatch with the array types having type hints
17:20unlink#^int means "cast me to the type int as needed"
17:20danlarkinunlink: but that's not what #^Integer means
17:21unlinkExcept here "the type int" has to be a user-defined type.
17:21Chousukethat would conflict with the meaning of #^Foo right now.
17:21danlarkintype hints aren't coercive
17:21Chousukethat's the main difference
17:22Chousuketype hints are just metadata; (int ..) etc are actual operations.
17:22unlinkyes
17:23Chousukeif you want type casts for classes, use cast :)
17:26danlarkincast doesn't do that
17:52ieureHm. So kotarak suggested that I try to use doseq to solve my SQL OOM issue, but I'm having problems with that. (with-query-results) doesn't return the result sequence, and I can't seem to return it from the body.
17:53ieureAnd doing: (with-query-results rs [query] (doseq rs (fn [row] ...))) fails with: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol
17:53ieureIdeas?
17:54hiredmanieure: have you read the doc string for doseq?
17:54hiredman,(doc doseq)
17:54clojurebot"([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."
17:54ieurehiredman, I read the API documentation, which is much the same.
17:55hiredmanwith bindings and filtering as provided by \"for\"
17:55hiredmananyway
17:55dnolenso why does this work again?
17:55dnolen,((ref +) 3 4)
17:55clojurebot7
17:55hiredmanyou are using it wrong
17:55hiredmandnolen: refs dispatch invoke to their values, I believe
17:56dnolenwhy them an not atoms?
17:56hiredman,((ref #{1 2 3}) 1)
17:56clojurebot1
17:56dnolenand not atoms
17:56hiredman,((atom #{1}) 1)
17:56clojurebotjava.lang.ClassCastException: clojure.lang.Atom cannot be cast to clojure.lang.IFn
17:56hiredmandunnp
17:56ieurehiredman, I'm sure I'm doing lots wrong, I really am not comfortable with Clojure yet.
17:56hiredmanpossibly it got overlooked
17:57hiredmanieure: (doseq [i (some collection/seq here)] do stuff to i here)
17:57hiredman,(doseq [i (range 10)] (print i))
17:57hiredmanugh
17:57hiredman,well?
17:57clojurebotjava.lang.Exception: Unable to resolve symbol: well? in this context
17:58hiredmanugh
17:58hiredmanI guess I should fix that
18:02hiredman,(doseq [i (range 10)] (print i))
18:02clojurebot0123456789
18:04ieurehiredman, I think I have it. It's running now, I'll see if it OOMs.
18:04ieurehiredman, Thanks for the pointer.
18:04hiredmansure
18:04ieureStill OOMs.
18:05hiredmancan you pastebin the code?
18:05hiredmanlisppaste8: url?
18:05lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
18:05lisppaste8ieure pasted "OOMing" at http://paste.lisp.org/display/80247
18:06hiredmanhow large are reach of the rows in the database?
18:07ieure16 cols per row, 155k rows.
18:07hiredmanbut, like, how much data is in each row?
18:09ieureCould be anywhere from 100 bytes to 1kb or so.
18:09hiredmanhmmm
18:10hiredmanI would remove the tokyo stuff, and just (doseg [row rs] (prn row))
18:11hiredmanto see if it is the result set
18:17lisppaste8ieure annotated #80247 "Still OOMing" at http://paste.lisp.org/display/80247#1
18:21ieurehiredman, Any thoughts?
18:21ieureSeems like the whole resultset is buffered, since I get "Running," a wait, and an OOM. I never see a single row printed.
18:23hiredmanhmmm
18:23hiredmanieure: sounds like it's time to up the memory limit on the jvm
18:26ieurehiredman, Crazy talk. 155k rows is my test data; I need this to handle 25m rows. Jacking up the memory limit isn't a solution.
18:27ieureI don't understand why rows can't be fetched individually and processed. This is the normal way one processes large datasets.
18:28ChousukeSounds like you'll have to use the resultset directly, without wrapping it in a seq
18:29dnolenisn't it possible to use loop recur here?
18:29dnolenand dump the stuff you're not using?
18:29dnolenprocess element, (rest coll)
18:29ieureChousuke, Not sure how to do that. I was trying (map), but it OOM'd, too.
18:30Chousukeif it's OOMing before you get anything printed, the problem might be with how with-query-result makes the seq
18:30ieureChousuke, That seems to be the case, I'm retrying with just a (prn "Done") as the body. Looks like it's going to die, too.
18:31hiredman~def with-query-result
18:31hiredmanouch
18:31Chousukeresults
18:31Chousuke~def with-query-results
18:31Chousuke~def with-query-results*
18:31ieureLooks like it's using (resultset-seq)
18:32ieurehttp://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/sql/internal.clj#172
18:33Chousuke~def resultset-seq
18:33hiredmanwhoops
18:33hiredmandamn
18:34Chousukelooks like it ought to be fine.
18:36ieureYet it isn't.
18:37hiredman~def resultset-seq
18:38ieureI'm using Clojure 1.0.0 and -contrib from SVN as of 05/04.
18:38Carkgood evening
18:38Chousukeactually I think the "rs" will hold to the head of the seq, but it shouldn't OOM before you've done work with it...
18:42Chousukeinstead of using (doseq [comment rs]), try using (if-let [comm (first rs)] (do (prn (genkey comm)) (recur (rest rs))))
18:43Chousukethe with-query-result body is wrapped in a lambda so it's a recur target
18:44ChousukeI'm not sure if the rs reference to the head is the real problem but my guess is that using recur should avoid that problem at least
18:46ieureChousuke, But the code OOMs even with just: (sql/with-connection *db* (sql/with-query-results rs [query] (prn "Done.")))
18:46Carka quick question : i need to parse text files, regexes won't do, should i use joshua choi's fnparse or kotka's parser ?
18:47Carkspeed is not an issue, i'm looking for ease of use
18:47hiredmanhaven't seen kotka's, but fnparse is pretty nice
18:47Chousukeis kotarak's parser actually usable nowadays?
18:47Chousukelast time I looked at it it was rather outdated.
18:47Chousukefnparse seems fine. it's using monads nowadays too :)
18:47Carkok well thanks you 2, i'll go for fnparse then =)
18:48hiredmanI am using an older version of fnparse
18:48hiredmanI think fnparse might currenlty be in the process of a rewrite to use monads or some other foolishnish
18:48hiredmanness
18:48hiredman:P
18:48Chousuke:p
18:49Chousukemonads are nice for parsing, though.
18:49Carkyep they say so
18:49Carkas long as i don't need to fully grok monads =P
18:49Chousukenah :p
18:50lisppaste8ieure annotated #80247 "Still OOMing" at http://paste.lisp.org/display/80247#2
18:51ieureChousuke, There's got to be something wrong with with-query-results, it OOMs no matter what's in the body.
18:51Chousukehmm :/
18:51Chousukeunfortunately, I can't tell what it is.
18:51hiredmanieure: sounds like it's time to up the memory limit on the jvm
18:52ieurehiredman, Right, but that shouldn't be a problem unless it buffers every row.
18:52hiredmanyou don't know that it is a linear thing
18:52Chousukeieure: it might even be that it's not the seq that is the problem.
18:52Chousukeor maybe it's generating too many thunks :>
18:53ieureWell, it works with LIMIT 5 in the query. :P
18:54Chousukeyou could actually try changing doseq to dorun
18:54Chousukeer
18:54Chousuke...
18:54Chousukenever mind
18:55hiredmanyou know the default jvm memory limit is only 128MB
18:56Chousukehiredman: that shouldn't be a problem, because it should never hold that much stuff in memory in the first place.
18:56ieureRight.
18:56Chousukeunless ResultSet itself caches too much
18:56Chousukewhich is a possibility.
18:57ctdeanWhat's an easy way to look at memory usage in the repl?
18:57Chousukeit might be that you're just very close to the memory ceiling before you create the resultset
18:57ieureI really don't want to solve this the ghetto way.
18:57ieureChousuke, This is the only code I'm running.
19:00Chousukehm :/
19:01ChousukeI really can't say aything more.
19:01Chousukethe resultset-seq looks okay, so...
19:01ieureWell, fuck.
19:01dnolenieure: post your problem to the list, some more eyes there as well.
19:02ieurednolen, Yeah, I was going to see about opening a ticket, too.
19:02ChousukeAll I can think of anymore is that it's ResultSet itself that runs out of memory.
19:02dnolenieure: don't bother with a ticket, until people have looked at it.
19:02ieurednolen, When you say list, do you mean the Google group?
19:02Chousukeyeah.
19:02dnolenieure: yes.
19:10hlshipI love lazy collections ... right up until my code loses all sense of cause and effect and I can't find the problem even w/ the debugger
19:55eeeanyone here use clojure-dev?
19:55eeeit seems to come with some of contrib but not all
19:55eeeis that right?
19:56memoizetoday, i just quit my dayjob so i can work on clojure projects full time at home :)
19:56eeeawesome
19:56eeei've thought of that
19:56eeehaven't done it
19:56eeewhat's your main project?
19:57memoizenothing in particular, im a clojure noob
19:57eeewow
19:57memoizejust want to retrain my mind to think in clojure, so now i've got until the end of 2010
19:57eeeyou are welcome to help me with my stuff, if you like
19:58eeei'm a noob to clj, too
19:58memoizei'd like to replace all my unix interaction with a clojure repl shell tho
19:58eeeinteresting
19:58memoizeso that i'm always in clojure on the computer, live breathe it, dont use any other tools
19:59eeeare you a lisper?
19:59eeeor new to that too
19:59memoizeno, i come from the land of python and perl
19:59eeewhat's the best way to get the latest contrib?
19:59memoizesvn update from the google project?
20:00eeei don't really want to build it
20:00eeei could do that
20:00eeeif it builds ok
20:00durka42http://clojure-contrib.googlecode.com/svn/trunk
20:00durka42actually there might be a jar there
20:00memoizeeee: it's just "ant" command, pretty easy
20:00durka42not sure
20:00durka42and it does build very easily
20:00eeeok
20:00memoizeeee: i can put up jar files for you if you're that lazy :)
20:00eeei guess i could get ant for my mac
20:00durka42where "build" means "zip up all the sources in a jar" unless you pass -Dclojure.jar=/path/to/clojure.jar on the command line
20:01memoizedurka42: does that option update clojure.jar to include clojure-contrib ?
20:01eeei'm working from eclipde
20:01durka42memoize: no, it compiles contrib against clojure.jar
20:01eeeso I'll want a jar of class files . . . unless contrib is all clj?
20:02durka42the sources are all clj of coures
20:02durka42course*
20:02eeei wouldn't have guessed that actually
20:02memoizei bet you can just point CLASSPATH to the contrib source and svn update regularly
20:02durka42i think eclipse can integrate with ant
20:03eeei'll try that
20:03eeeyeah
20:03durka42memoize: that might work
20:03memoizeeee: but you would need to get used to ant anyways if youwant to track clojure trunk; you working only against 1.0?
20:04eeei don't pay attention . . . whatever eclipse-dev uses
20:04memoizemake sure its at least using 1.0 if you don't care :)
20:05eeegonna try svn
20:07eeewhat are .cs files, I see in the console, I wonder
20:07eeeclojure source?
20:07chessguycsharp? :)
20:07eeegood guess
20:07eeechessguy! long time
20:08eeei got the a-star done
20:08chessguycool
20:08eeehmmmmm i remember seeing a graph package
20:09eeegonna do some prims or djikstra now
20:10eeei see. i didn't realize a bunch of stuff would just be at the clojure-contrib level
20:10eeeas files
20:11eeethat's wjere graph is
20:12technomancyI've got to say, I'm not a fan of the deps.zip approach
20:12durka42i believe that's why package managers were invented
20:12technomancydurka42: yeah, tell me about it
20:12danlarkinfinally, someone agrees with me :)
20:13technomancyunfortunately one of the dependencies is a proprietary amazon jar that's not extant in any public repositories. =(
20:13technomancydurka42: I was playing around with "corkscrew"
20:13technomancyit vaguely sounds like something you'd use to manage jars
20:13durka42enclojures and clojureboxes are taken
20:14technomancydurka42: mvn does a great job modulo the act of writing a bunch of XML
20:14technomancyI think we could wrap mvn in a delicious sexp layer and get something fairly rockin'
20:15technomancydanlarkin: did you see the pom I put in clojure-http-client?
20:15danlarkintechnomancy: I saw that you added it, but didn't look at it
20:16technomancydanlarkin: dysinger created clojure-pom which acts as a sort of base setup for any clojure project, and I just build from that.
20:16technomancybasically all you do is add contrib (if you use it), and you're good to go. ends up being like four lines.
20:17danlarkinbut do you need dysinger's thing installed somewhere or something?
20:18technomancydanlarkin: yeah, for now, but I'm going to get him to push it to a public repository so you won't need to do anything but "mvn install"
20:19technomancydanlarkin: what do you do for dependencies?
20:20danlarkintechnomancy: in terms of libraries I write? just list them in the readme. In terms of dep management for myself, ~/clojure/src/
20:21eeethis was a whole can of worms wanting to depend on contrib
20:21eeei find a lot of time always spent on config.
20:21technomancydanlarkin: so if you're writing an application that depends on clojure-json, then you just manually copy all the .clj files into src/ or deps/ of your project so it's on the classpath? or what.
20:22eeeso if someone else did your config, then yes, clojure serves as a great functional language where you spend most of your time in your domain in your business rules, etc.
20:22eeebut that's a big if
20:22danlarkintechnomancy: oh, no, my clj script adds add src/ directories and .jars in ~/clojure/src/ to the classpath
20:23technomancygotcha
20:31memoizeeee: there's nothing holding contrib back from using the latest goodies, nor would we want to until they decide on a 1.0 release
20:31eeei figured out my main problem
20:32eeeyou can't see things in the namespace browser until you 'use' them
20:32eeemy next problem is: where would tests be if there are any. like so I can see usage
20:33eeei'd like to understand the clojure-contrib.graph thingy (namespace?)
20:33technomancyeee: I have a test/ dir in the project toplevel next to src/
20:34technomancythen the namespaces in test/ map to those in src but with the second-to-last segment being test
20:34technomancyso org.clojure.foo is in src/org/clojure/foo.clj and tested with org.clojure.test.foo in test/org/clojure/test/foo.clj
20:34eeei found this. is that what you mean? wasn't nect to src http://www.google.com/codesearch/p?hl=en#oduOV9Ab97s/trunk/src/clojure/contrib/test_contrib/test_graph.clj&amp;q=graph%20package:http://clojure-contrib\.googlecode\.com
20:35technomancycontrib does it differently
20:35eeeok
20:35eeei get it, you were answering as to what your convention is
20:36technomancyoh, thought you were asking how to structure your own stuff
20:36eeei was looking specifically for the graph tests, but that is good to know that you are conscious of a need for a convention
20:36eeeyeah, sorry
20:37technomancyI don't like how contrib does it because I need to be able to calculate the namespace that tests a given namespace and vice versa so I can teach my editor how to toggle between tests and implementation.
20:37eeesounds like you are at an advanced level
20:37technomancyadvanced elisp maybe. =)
20:38technomancynot being able to toggle between test and impl sucks though
20:38eeei always say emacs is the reason lisp isn't more popular (ducking yet again)
20:38technomancyafter working with clojure elisp feels a bit like tarzan-speak
20:38eeecntl-s doesn't save
20:38eeeso it's broken
20:39eeecopy and paste are broken too
20:39durka42c-x c-s
20:39eeebecause they aren't cntl-c and cntl-v
20:39technomancyeee: the kill ring is far more powerful than "standard" clipboard mechanisms; gimme a break.
20:39eeeso most users punt in 5 seconds
20:39durka42(aquamacs still has cmd-s bound to save :))
20:40technomancybut elisp feels like "me get list. me alter list. you wait while I/O blocks process without concurrency primitives."
20:40eeei'm sure it's better
20:40eeethan most windows tools
20:41RaynesAfter working with Clojure, Scala feels like a scary new world where I'm lost and I can't find the golden coconut that will take me back home. But I'm getting used to object orientation now, so I'm having fun learning Scala. I just miss Clojure.
20:41technomancywell lots of people claim that swing is "broken" because it doesn't look like the rest of the OS. different isn't necessarily broken.
20:41technomancyif everything has to be the same as what you're used to, then it causes stagnation.
20:42eeethat's covered well in two of my favorite books
20:42eeezen and the art of MM
20:42technomancyRaynes: you have to give the red key to the guard, then you can get to the room with the golden coconut.
20:42eeeand the sequel
20:43technomancyRaynes: watch out for grues though.
20:43eeeso what's the deal with structs
20:44eeei know that makes no sense
20:44eeebut
20:44eeei'm not really sure what I do
20:44eee(struct directed-graph #{:a :b :c :d :e} {:c #{:b :a} :e #{:c} :d #{:c :e} :b #{:d :a} :a #{:d :b}})))
20:45eeeso then I (let) something to a 'directed graph' struct
20:45eeeand then call functions on it?
20:45Raynestechnomancy: Thanks!
20:45guineaWhat's the best way to construct and print a string that has number in it, in the form of java integers?
20:45durka42(doc format)
20:45clojurebot"([fmt & args]); Formats a string using java.lang.String.format, see java.util.Formatter for format string syntax"
20:46durka42,(format "%d" 3)
20:46clojurebot"3"
20:46guineasweet. thanks!
20:46danlarkineee: structs are not classes
20:48Raynesdanlarkin is a class!
20:51arohnerif I call (fn inside a function body, does that create a new fn every time the function is called?
20:52danlarkinarohner: pretty sure it does, yes
20:53arohnerbut it's only compiled the one time?
20:53arohneri.e. each run through the function creates another instance of class fn_12345, and all instances of class fn_12345 have the same bytecode?
20:54guineahow should I print a newline?
20:55arohnerguinea: (println) ?
20:55arohneryou can also do (println "foo bar"), but that doesn't have the formatting options of (format)
20:56durka42or put \n at the end of the string
20:56dreisharohner: Yes, it is only compiled once, by eval.
20:57guineadurka42: \n didn't work within format. I was just reading the javadoc for it. But a separate println after the (.write (format ...)) would work.
20:58arohnerguinea: are you trying to print to the screen?
20:58arohner,(print (format "first line\nsecond line"))
20:58clojurebotfirst line second line
20:58arohnerok... that works on my terminal
20:59guineaarohner: no, to a java filewriter
20:59hiredmanclojurebot tends to eat newlines
20:59arohnerguinea: are you on windows?
21:00hiredman~newline
21:00clojurebotthanks; that was delicious. (nom nom nom)
21:00durka42(System/getProperty "line.separator")
21:02guineaoh, it does work in newline
21:02guineaI just did it wrong
21:02guineaI mean, newline works within format
21:02guineaarohner: no, linux
21:34guinea~newline
21:34clojurebotthanks; that was delicious. (nom nom nom)
21:35technomancythat's a new one
21:38dreish,(println "In reference to the fact that clojurebot\neats\nnewlines.")
21:38clojurebotIn reference to the fact that clojurebot eats newlines.
21:39cp2i wish clojurebot would be my friend
21:39durka42clojurebot: whose job is it to be cp2's friend?
21:39clojurebotAlles klar
21:40durka42that used to work
21:40cp2:(
21:40dreish~whose job
21:40clojurebotwhose job is it to be cp2's friend?
21:41technomancyclojurebot: whose job would it be to be cp2's friend?
21:41clojurebotwhose job is it to be cp2's friend?
21:41technomancyclojurebot: stop copying me.
21:41clojurebotwe can't stop here! this is bat country!
21:42durka42clojurebot: whose job is <reply>that's <someone>'s job
21:42clojurebotAck. Ack.
21:42durka42~whose job
21:42clojurebotthat's <someone>'s job
21:42RaynesLOL
21:42RaynesFear and Loathing.
21:43hiredman~who's job would it be to right the wrongs of the world?
21:43clojurebotwhat the world needs is more higher order functions
21:44hiredman:\
21:44technomancyhe has a point though
21:44hiredmanindeed
21:46dnolentechnomancy: do you have any good examples of parsing lines from a file using elisp? You seem to be the resident elisp expert :)
21:46technomancydnolen: what kind of file?
21:47technomancyI did something sort of like that in my couchdb client, though it's very simplistic.
21:47dnolenjust a text file, I'm sick of managing my classpath by hand.
21:47dnolenI'm building a simple library management system using GAE
21:47dnolenso that I can type
21:47dnolen(install 'library-name)
21:48dnolenfrom the REPL.
21:48dnolenbut in order this to work in Emacs I need all classpaths to be a text file.
21:48dnolenin a text file.
21:48durka42how does GAE come in to that?
21:48technomancydnolen: in a nutshell: (save-excursion (while (search-forward-regexp my-pattern nil t) (do-something-with (string-match 1))))
21:49dnolenno having to pay for hosting.
21:49dnolentechnomancy: that's if I have the file open already and loaded into a buffer correct? I found that much.
21:49technomancyerr... hosting static files is very cheap. if you're worried about that I'll give you a shell account on my dreamhost. =)
21:50technomancyright; you'd need to find-file first
21:50technomancydnolen: you can't do much with a file unless it's in a buffer
21:51technomancyyou could also use url-retrieve if it's a remote file, relax.el has a few examples of that
21:52dnolencool, the other advantage of GAE is just scalability (maybe hosting jars, jnis), speed, security. I don't want to have to code that either.
21:53technomancyI'd strongly advise against a library management system that needs a dynamic server. it's much easier to build up a set of static files.
21:54technomancyrubygems, maven, and elpa all go this route.
21:54dnolenhmm what do you mean by dynamic server?
21:55technomancyI mean more than a directory with files in it.
21:55technomancyif any user operation causes code to run outside of apache or nginx or whatever, it's more complicated than it needs to be
21:55dnolenlike you mean on the client?
21:55technomancysorry, server-side code
21:56dnolenbasically I'm starting off just by creating a wiki, I'm not even hosting files in the beginning.
21:56technomancyoh, ok
21:56dnolenjust a json data about a where a library lives.
21:56durka42unless it looks like a simple list of files on the server but you're faking it with some fancy database or whatever
21:56technomancyI assumed you were using GAE for dynamic responses to client requests.
21:56dnolenthere's a client library that checks the server to resolve the library location.
21:56dnolendownloads the file, unzips, update the classpath.
21:57technomancystill missing the GAE connection
21:58dnolenjust for the hell of it, I don't feel like hosting it myself, plus then people can also download the project from GitHub, develop locally to improve and it's easy to push up patches.
21:58technomancygotcha
21:58technomancydnolen: you should take a look at my corkscrew project
21:58dnolenlink?
21:58technomancyhttp://github.com/technomancy/corkscrew
21:59technomancyit can already handle dependencies in git or svn or just grabbing a jar over HTTP
21:59technomancyplanning on adding mvn repo support as another backend so transitive deps would work
21:59technomancysince that's where the real tricky stuff comes into play
22:00technomancyclojurebot: corkscrew is a proof-of-concept build system and dependency manager (http://github.com/technomancy/corkscrew)
22:00clojurebotIk begrijp
22:00dnolenheh looks almost identical to what I'm doing in terms of lib def format :)
22:00technomancyheh
22:00technomancylet's join forces
22:01dnolencool! I want this library thing fixed bad.
22:01technomancyactually the problem with corkscrew is that the fun stuff is basically done, the hard parts remaining are just integrating with the maven Java API
22:01technomancydnolen: you're not the only one. =)
22:01technomancyI've been meaning to announce on the mailing list, but I was waiting till I had proof-of-concept mvn integration.
22:05danlarkinoof, I hate the 80/20 breaks
22:06technomancydanlarkin: yeah, if you ignore transitive deps, you can practically solve the problem in an afternoon.
22:07danlarkinI wish I could ignore 20% of the problems at work :)
22:10technomancyinteresting article: http://enfranchisedmind.com/blog/posts/scala-not-functional/
22:11technomancymakes a good case against the "Can't OOP and FP just get along well together?" mentality.
22:12technomancydanlarkin: care to take a look at corkscrew and comment?
22:12technomancywould love to get some more eyes on it.
22:14danlarkintechnomancy: I very much like the idea
22:14danlarkinI will have to look at your implementation later, though
22:14technomancyright, no big deal
22:33technomancyhow do folks generally do logging? just regular log4j?
22:41arohnertechnomancy: that's what I do
22:41cp2asdf etc
22:43technomancyarohner: it's struck me as kind of noisy out of the box, but I guess you can deal with that
22:43arohneryeah. I have a function that's just (log severity "type" "message")
22:44arohnerand I could get that down smaller if I wanted
22:44technomancyoh, I meant the output format. =)
22:44arohneroh :-)
22:44technomancyin the context of some of the apache libs it was pretty spew-happy
22:44arohneryeah, that can be dealt with too
22:44arohnerthough I'm used to reading apache logs
22:44arohnerthat, and there are good log viewers out there
22:45technomancylike less? =)
22:45technomancyor grep -v INFO ? =)
22:46arohner:-)
22:52technomancyis it appropriate to release projects with the groupId of "org.clojure" even if it's not officially related to clojure?
22:57jmanesshas anyone seen an exception like this when compiling .clj? Exception in thread "main" java.lang.IllegalStateException: get already refers to: #'clojure.core/get in namespace:
22:57jmaness"get" isn't even in the .clj file
22:58technomancyjmaness: are you "use"ing a library that defines a "get" function?
22:58technomancytypically you want to require it :as something instead
22:58jmanessah probably so. clojure.http.resourcefully
22:59technomancyjmaness: yes... that would be my fault. =)
22:59jmanessah ok cool thanks. I'll try "require"
22:59technomancyjmaness: I'm on the fence about that. I think it's cute and maps to HTTP well, but it's unfortunate that you can't "use" it like any other lib
22:59technomancyjmaness: the readme explains it.
23:00technomancybut... having to read the readme carefully to try out the library without getting errors is unfortunate.
23:00technomancyI might end up renaming it so you don't have that problem
23:00jmanessah thanks. sorry I missed reading the README :)
23:01technomancyhonestly I'd prefer it if clojure.core didn't define "get" since I perform HTTP get requests far more often than I use core's version of get.
23:01technomancybut that's unlikely to change. =)
23:02bradfordi want a function that applies a map of functions to a map fo values of the same keys.
23:02bradford(def test-map {:a 10 :b 5})
23:02bradford(def test-fns {:a #(%1 > 5) :b #(%1 < 5)})
23:03technomancy(map #((test-fns %) (test-map %)) (keys test-map)) is that too verbose?
23:04technomancyjmaness: other than that silly get problem, is clojure-http-client working well for you?
23:04technomancyI'm interested in feedback for improving it.
23:05durka42bradford: (merge-with #(%1 %2) test-fns test-map)
23:05technomancydurka42: dang; that's slick
23:05jmanesstechnomancy: so far so good. I'm trying to get basic auth working
23:06technomancyjmaness: ah cool; I haven't done anything with auth yet.
23:06technomancyjmaness: patches welcome. =)
23:07jmanesstechnomancy: sure, I've cloned clojure-http-client, so as soon as I get something working, I'll send it your way
23:08technomancycool. nothing like scratching your own itch.
23:11bradfordi don't thing merge-with does what i want
23:12durka42then i misunderstood what you wanted :)
23:12bradfordi think merge-with is for mergeing many maps and using a single function to resolve merging duplicate keys
23:13bradfordwhat i am doing here is applying each function in a map fo function to each value in a map of values
23:13durka42so the way i called merge-with above, on duplicate keys it uses #(%1 %2), which is function application
23:13technomancybradford: ah, so every function gets called with every value?
23:14bradfordright
23:14technomancyyeah that's different
23:14durka42what does (magic test-fns test-map) return?
23:14technomancyhow would the return value look?
23:14technomancysounds two-dimensional
23:15bradfordtheresult of this function for the example I gave is {:a true :b false}
23:15danlarkinresourcefully/get strikes again!
23:15durka42Clojure=> (merge-with #(%1 %2) test-fns test-map)
23:15durka42{:a true, :b false}
23:15technomancydanlarkin: you can say I told you so now. =)
23:16technomancyrename it to hget?
23:16bradforddurka42: i get: .Integer cannot be cast to clojure.lang.IFn
23:16durka42bradford: fix the functions in test-fns
23:17bradforddurka42: bwaahahahah! thanks man
23:17technomancyhehe
23:17technomancybradford: also: if a #() fn has only one arg you can use % rather than %1
23:19eeeit looks like clojure-contrib.graph doesn't define weighted graphs?
23:19eeewhat if I wanted to add that concept?
23:25eeei guess I can use a hash-map instead of a hash-set for the neighbors
23:39bradfordif i get: ({:a 1, :b 0} {:a 0, :b 1}) from a for expression...
23:39bradfordand then try to pass it to something that expects a number of maps {} {} then how to pass it?
23:40eeeexpects a number of maps
23:40eeein a list?
23:40eeei fixed number?
23:40eeea
23:41bradford(defn counts [fns map] (merge-with #(+ %1 %2) (for [x map] (merge-with #(%1 %2) fns x))))
23:41bradfordproblem is with the outer merge-with
23:41eeeit sounds like you are saying how do I send a list of maps to something that takes a list of maps
23:41bradfordi know :-) ...it seems that way
23:41eeelemme look
23:42bradford(def test-fns {:a #(if (> % 5) 1 0) :b #(if (< % 5) 1 0)})
23:42bradford
23:42bradford(def test-map [{:a 10 :b 5} {:a 4 :b 1}])
23:42bradfordthat are what i am passing to this counts fn
23:44eee,(doc merge-with)
23:44clojurebot"([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."
23:44hiredmanbradford: you use apply
23:44eeei was thinking of reduce
23:45bradford(defn counts [fns map] (apply merge-with (cons #(+ %1 %2) (for [x map] (merge-with #(%1 %2) fns x)))))
23:45bradfordusing apply + cons
23:45eeereduce the list comprehension using merge-with as the function
23:45bradfordseems like there must be a better solution to this little coding problem