#clojure logs

2009-09-25

00:03drhodesis there anything built in for doing something like (pow 3M (with-precision 20 (/ 1 3M)))
00:08slashus2no
02:09tomojanyone know how to have slime setup for both clojure and, say, common lisp?
02:21vytomoj: Just introduce related slime-lisp-implementation entries.
02:33pixelmanI'm looking for but not finding a function similar to ruby's detect or find. which is like filter but just returns the first match. How can I do something like this in clojure, recur?
02:34tomoj pixelman: find-first in clojure.contrib.seq-utils does it
02:37pixelmantomoj: thanks!
02:40pixelmanah, seq utils isn't in my version of clojure contrib
02:41tomojyou sure?
02:41tomojmaybe it's old I guess
02:41pixelmanah no it was there
02:41pixelmanjust misspelled clojure :)
02:41tomojanyway this is the definition of find-first: (defn find-first [pred coll] (first (filter pred coll)))
02:41vypixelman: filter returns a lazy list, so (first (filter f seq)) should do what you're looking for. (I dunnot if there exists something similar to FIND-IF oor FIND-IF-NOT of CL.)
02:41tomojso.. pretty simple
02:43pixelmandidn't find it when I searched because it wasn't included.
02:44pixelmanok by lazy that means not all of the list will be evaluated
02:44pixelman?
02:44pixelmanor that it will be evaluated only when function is called?
02:47vyAFAIK, `first' will force the evaluation of the very first element only.
02:49pixelmanok!
03:06vypixelman: See clojure.contrib.seq-utils/find-first
03:06vyhttp://github.com/richhickey/clojure-contrib/blob/master/src/clojure/contrib/seq_utils.clj#L170
03:07pixelmanvy: thx! seems like it will not evaluate unnecessary stuff!
03:23LauJensenGood morning all
04:16pixelman,(Math/round (+ 23/9 0.0))
04:16clojurebot3
04:17pixelmanis there a simpler way to round down a ratio to an integer?
04:19crios__guten tag!
04:20jdz,(float 23/9)
04:20clojurebot2.5555556
04:20LauJensen,(int (+ 0.5 (/ 23 9)))
04:20clojurebot3
04:24LauJensen,(int (+ 0.5 23/9))
04:24clojurebot3
04:25LauJensenpixelman: Thats the fastest simplest bestest way to go :)
04:25pixelman:)
04:26pixelman,(Math/round (float 23/9))
04:26clojurebot3
04:27LauJensenpixelman: I don't think that's faster or better, do you ?
04:28pixelmanLauJensen: :) I want it to work for any ratio
04:28LauJenseni5 2ill
04:29LauJensenoops
04:29LauJensenit will
04:29LauJensen,(int (+ 0.5 3/4))
04:29clojurebot1
04:29LauJensen,(int (+ 0.5 1/4))
04:29clojurebot0
04:29pixelmanLauJensen: I missed your call to (int first
04:30pixelmanLauJensen: yeah, it'll work :)
04:30LauJensenit sure will baby :)
04:30LauJensenSomebody from in here taught me that 6 - 8 months ago, saying it was an old C trick
04:32pixelmanC is full of stuff like that
04:33pixelmanare you from denmark?
04:33LauJensenYep
04:33pixelmanThen you'll probably appreciate the humor of this: http://unix.se/Gubb-C
04:34eevar2you want to round down? - I'd shoot for Math/floor and let the JVM inline as neccessary
04:34LauJensenhaha :)
04:38pixelmanthere seems to be a round in clojure contrib that works with ratios
04:38pixelmanI'll use that I think
04:39pixelman,(round 2/3)
04:39clojurebotjava.lang.Exception: Unable to resolve symbol: round in this context
04:40pixelman,(clojure.contrib.math/round 2/3)
04:40clojurebotjava.lang.ClassNotFoundException: clojure.contrib.math
04:58AWizzArdLauJensen: You do json with compojure?
04:58LauJensenIn one yes, case
04:59AWizzArdMy client makes a POST request to Compojure, and writes into the request header {"content-type" "application/json"}, and puts into the body a json form.
04:59AWizzArdHow can I read a POST body in Compojure? (= the json form)
05:00LauJensenuse contribs json reader (read-json (:body request))
05:04AWizzArdLauJensen: (defroutes awizzard (POST "/echo" (fn [x] (:body x)))) here (:body x) is a #<Input org.mortbay.jetty.HttpParser$Input@c9de16>. Is there a way to extract the json string out of it?
05:06LauJensenNo I think that's taking the long route. Could you add a debugger like (POST "/echo" (doseq [l request] (println l)) - I would be surprised if you didn't see the raw JSon in there
05:11sfuentescan someone explain what a lazy sequence means?
05:12noidi_sfuentes, it's a sequence whose values are generated only when needed
05:12noidi_that way you can have an "infinite" sequence
05:13noidi_,(take 3 (repeat :foo))
05:13clojurebot(:foo :foo :foo)
05:13noidi_(repeat :foo) returns a lazy sequence full of :foo
05:13noidi_,(doc repeat)
05:13clojurebot"([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."
05:14noidi_note that lazyness does not necessarily mean that the sequence is infinite
05:15sfuentesi see.
05:15AWizzArdLauJensen: unfortunately the json string really doesn't show up. I tried it this way: (http-agent "http://localhost:8080/echo&quot; :method "POST" :body "{\"echo\" 123}" :headers {"content-type" "application/json"})
05:15sfuentes,(repeat :foo)
05:15clojurebotEval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space
05:15LauJensenAWizzArd: pmsg
05:16sfuentesooops
05:16sfuentesdid i break that?
05:16Chousukeclojurebot: ping
05:16clojurebotPONG!
05:16noidi_if you do that, the repl will try to print all of the sequence
05:16noidi_which means that all of the (infinite) sequence has to be generated :)
05:16sfuentesi am so sorry.
05:17Chousukesfuentes: don't worry, it doesn't affect clojurebot
05:17sfuentesi thought it would assume a sequence of 1
05:17ChousukeI suppose it'll just get the OOM exception and then the seq generated so far will get GC'd
05:19noidi_,(+ 2 2)
05:19noidi_,(doc repeat)
05:19clojurebot4
05:19noidi_hmm, did that really break clojurebot? :D
05:19jdzshould not have
05:19noidi_maybe a bug in the sandbox?
05:19clojurebot"([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."
05:19Chousukelaggy.
05:19jdzclojurebot had to catch up to the infinite sequence :)
05:20jdzyou know, it takes time to GC an inifinite sequence
05:20jdzbut clojurebot is fast
05:20jdzrelatively
05:20Chousukewell, it gets GC'd lazily :)
05:21Chousukethe not-yet-generated items are GC'd only when needed :D
05:26sfuentesyou guys are geeks
05:26sfuentesi like that
05:30sfuentesso what's the difference between using ";" versus "(comment)" ?
05:30Chousukesfuentes: 'comment is actually a macro
05:30Chousukeso this can happen:
05:30jdzthe stuff in comment must be valid clojure expressions
05:30Chousuke,(comment #<error>)
05:30clojurebotUnreadable form
05:31Chousuke,5 ;#<no error>
05:31clojurebot5
05:32sfuentesso why would use ever use (comment ) ?
05:32Chousukeit's handy for commenting out entire expressions
05:32clojurebotfor is a loop...in Java
05:32jdzespecially if you have expression-aware editor, like emacs
05:33Chousukeor code that could be evaluated manually in a repl for example
05:34sfuentesok, i see.
05:34atomethe other diffence is (comment) evaluates to something
05:35atome,(nil? (comment blah))
05:35clojurebottrue
05:35Chousukethe definition of comment is simply (defmacro comment [& body])
05:35atomewhich tripped me up a few times, eg if you use (comment ) at the end of a function it'll return nil
05:36sfuenteswell i'm glad to see that folks in this channel are very helpful. thank you all.
05:37LauJensennp :)
05:37LauJensen(notice how I sneak in to steal the glory)
05:39jdzyou can't steal it. stealing presumes ownership ;)
05:39Fossi... glorypirate
05:41LauJensenjdz: Man it's hard to keep you happy :)(
05:42jdznah, i just remembered a quote from "V for Vendetta"
05:43jdzi'm overall a very happy person :)
05:52sfuentesdefn- means scoped to current file?
05:53Chousukeprivate to the namespace
05:54sfuentesok
05:55Chousukethough it's pretty easy to override if someone really wants to. but don't worry about that :)
05:55Chousukeif someone goes and uses your private functions and things break, it's their fault :P
05:56sfuenteslet them clean their mess :)
06:13ambienthas anyone written games with clojure yet?
06:13ambientactual games, not something like minesweeper :p
06:15jdzyour definition of "actual game" is very subjective
06:16ambientevent loop, simulation-type engine, realtime
06:17ambientlet's say asteroids done with opengl
06:17jdzlook for "pong" in mailing list
06:17jdzthat fits your description
06:18jdznot the best example of idiomatic clojure code, though
06:19ambientseems that it has been updated for more idiomatic clojure :)
06:19ambienthttp://jng.imagine27.com/articles/2009-09-12-122605_pong_in_clojure.html
06:19ambientthanks
06:30RomanRoeThe clojure api doc says that watcher are experimental. Is this still up-to-date or can I consider them to be stable?
07:13yasonHow to force symbol capture in defmacro? I'm experimenting with a macro that expands to defmethod call with a fixed set of argument symbols, and I need to introduce those plain symbols in the macroexpansion so that the body can refer to the arguments.
07:13yasonBy creating the dang (defmethod ...) call as a list, instead of backquote?
07:19LauJensenambient: I was working on one when I had the time for it, but you can finish it if you like
07:19LauJensen~sofiaba
07:19clojurebotsofiaba is http://wiki.github.com/Lau-of-DK/sofiaba
07:29Chousuke,`(foo ~'foo) ; tason
07:29clojurebot(sandbox/foo foo)
07:30Chousukeyason * :P
07:31yasonChousuke: much easier :)
07:32yasonChousuke: I'm still not that familiar with that stuff (namespaces, fully-qualified symbols and just symbols)
07:33pixelmanI want to grab and inspect the request object? in compojure. how can I do that? (pprint request) doesn't give any output anywhere for me
07:34pixelmanhm maybe I just can print it to a page, but it would be nice to get it on the log, or in the repl
07:35Chousukeyason: fully-qualified symbols are just symbols too. it's just that neither let nor fn allow them so you can't accidentally capture names.
07:37yasonChousuke: Yeah, I figured out a bit of that each time I used syntax quote for creating a template of something
07:38Chousukecapturing names is rarely needed though.
07:38yasonChousuke: then I got lots of errors because all my symbols had turned into user/mysymbol and I tried to de-qualify them for later processing :)
07:38Chousukemost of the time it's better to just take the names you want to bind as parameters
07:41yasonChousuke: that would work but would cause lots of duplication on the user side :)
07:44yasonChousuke: anyway, thanks for ~' -- it really makes sense now that I thought about it
07:50crios__Could I ask a bit challenging question?
07:50crios__What are the application domains for wich Clojure can hope to become a mainstream language, in your opinion?
07:50LauJensenFor those interesting in rendering chaotic functions in 80 lines of code: http://www.dzone.com/links/chaos_theory_vs_clojure.html
07:50LauJenseninterested :)
07:51Fossicrios: anything java is currently
07:51crios__Are you serious about that? :)
07:51Fossisure
07:52Chousukemaybe not the super high performance stuff though. yet, anyway
07:52Fossii wouldn't want to write a single line of java again if it were up to me
07:52FossiChousuke: well, i have rarely seen super high performace java "stuff"
07:52clojurebot
07:55pixelmanI've seen a lot of high-performance java stuff made in vain, designed to for loads exceeding 1000 times the actual use :)
07:57pixelmana lot of java programs are designed performance first usability, maybe later...
07:58pixelmanI like not having to fall back on C for high performance stuff though
07:59yasonpixelman: I can write a Python program that is designed for loads exceeding 1000 times the actual use. It just depends on the problem space :)
08:01pixelmanyep. Most high performance stuff in python use C functions though, that's why it's fast.
08:02pixelmanthere are some really good stuff in python for number crunching :)
08:02ambientnumpy, mainly
08:03Fossipixelman: same here
08:04jdzi'd prefer (iterate (partial * 2) 1) over (iterate #(* 2 %) 1) any time of day
08:04Fossithe most "high performance" code has been a smallish demo we wrote that reads some data from a memory-mapped file a
08:05Fossiand processes them
08:05Fossibut there is no reason that couldn't work with clojure i guess
08:05Fossialthough the immutable datastructures can get a little heavy for the gc (especially on dalvik)
08:06pixelmanhigh performance stuff I dont like working with is when writing an app and everything with the db is a stored procedure.
08:07pixelmanbut maybe it just sucks to work with from java
08:08pixelmanin lisp, maybe it's possible to write a really clean api
08:10pixelmanbtw. is the a way to easily wrap a java access so that it'll just return nil for a null access? like (.getFoo myVoidObject)
08:10pixelmaninstead of an exception?
08:11Chousuke(doc .?.)
08:11clojurebot"clojure.contrib.core/.?.;[[x form] [x form & forms]]; Same as clojure.core/.. but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). Examples : (.?. \"foo\" .toUpperCase (.substring 1)) returns \"OO\" (.?. nil .toUpperCase (.substring 1)) returns nil "
08:11pixelmanChousuke: thanks!
08:11ChousukeI think there's also -?>
08:12pixelmanpretty cool
08:14LauJensenjdz: Are you dissing me again?
08:15jdznope, i'm dissing #() sintax, if anything
08:16LauJensenIt's cool :)
08:16Chousuke#() still has its uses though
08:17pixelman,(.?.toString nil)
08:17clojurebotjava.lang.NullPointerException
08:17jdzyes, but when everything else fails only
08:17pixelmanhow would I go about to use .?. ??
08:17Chousukewith comp and partial it's sometimes difficult to see what the actual operation is
08:17Chousukenot in this case though.
08:17jdzpixelman: (.?. nil .toString)?
08:18jdzChousuke: sometimes. is (partial + 2) the case?
08:18pixelmanjdz: thankx. am I stupid or what :)
08:19Chousukejdz: I'm sure I can find you an example from clojurebot's source. a moment... :)
08:20jdzdon't take me wrong. i do use #() in places, but as i said, only when everything else makes the code less readable.
08:20jdzit might be just me...
08:20LauJensenI agree jdz, and I'm glad I have you to point it out to me - I really am :)
08:20Chouser(->> (range 10) (filter odd?) (remove #(< 3 % 7)))
08:21LauJensen~def ->>
08:21clojurebotNo entiendo
08:22LauJensenChouser, it's like -> but runs partial on all expressions?
08:22cgrandLauJensen: it's like -> but adds in last position instead of second
08:22jdzi think it's like ->, only adds the parameter to the end of argument list, not front
08:23LauJensenThanks guys :)
08:23jdznever used it myself yet
08:24jdzChouser: that example of yours is where the use of #() is justified and improves code comprehension
08:25Chouserjdz: because 'partial' wouldn't work?
08:29jdzChouser: yes, it does not fit here
08:29jdzbut then, putting arbitrary constants in code is bad
08:30Chouserall of that code was arbitrary. :-)
08:30jdzthe remove expression could be replaced by something like (filter good-enough-for-me?)
08:30jdzgiving names to things is good
08:30Chouser(def good-enough-for-me? #(< 3 % 7))
08:30jdzin the long term
08:30Chouser:-)
08:31Chousernow I'm just antagonizing you.
08:31jdz(defn good-enough-for-me? [n] (< 3 n 7))
08:31jdzreplace n by something meaningful for the problem domain
08:31clojurebotfor is a loop...in Java
08:31jdzclojurebot: orly?
08:31clojurebotexcusez-moi
08:32Chousukethat for factoid triggers way too often
08:33jdzin the end, code that is written and uses #() is a lot better than my unwritten code that does not use #() everywherne
08:33jdzumm, everywhere
08:35Chousukeheh
08:36Chouser"worse is better" in a nutshell
08:37Chousukeyou could remove many of the #()s if java methods were automatically wrapped in functions when used as values
08:38ChouserChousuke: yes, that most annoying ones at that.
08:38Chousukebut I don't know if doing that has any side-effects
08:39ChouserAnd it wouldn't even be that hard for the complier to do it. But then in order to add a type hint (not uncommon in such situations) you'd simply have no way at all to do it and would have to go back to #(.foo #^Hint %)
08:39Chouser(map #^{return-tag String} .toUpperCase ["one" "two"]) ; bleh :-(
08:40Chouser(map #^{:return-tag String} .toUpperCase ["one" "two"]) ; even worse
08:41jdz(map (java-method .toUpperCase String String) ["one" "two"])...
08:41Chouser(map .toUpperCase #^[String] ["one" "two"]) ; hmmm...
08:41Chouser,(map #(.toUpperCase #^String %) ["one" "twp"])
08:41clojurebot("ONE" "TWP")
08:42Chousukehm
08:42Chousukereminds me, I still have to fix my implementation of #() to preserve any metadata :/
08:43ChouserChousuke: like for its return value?
08:43Chouserer, wait, what?
08:43Chousukein my reader.
08:44ChousukeI should also find the time to finish the thing but I've been a bit busy with studying lately
08:44Chouseryeah, but metadata on what? a fn?
08:44Chousukethe #^Foo tag on %
08:44Chouseroh, yeah, on %
08:44Chousukeas it is now my implementation simply replaces the % symbols with gensyms
08:44ChouserI don't the the reader does anything special with % anymore
08:44Chouser,'%
08:44clojurebot%
08:45Chousukeit does, within #() :/
08:45Chousuke,'#(foo %)
08:45clojurebot(fn* [p1__3943] (foo p1__3943))
08:45Chouseroh
08:45Chouserhuh
08:45ChouserI wonder why
08:45LauJensenChouser: Did you see this? http://www.dzone.com/links/chaos_theory_vs_clojure.html That's my second post which turned jdz against #() :(
08:45jdzi'd like the following to work, too.
08:46jdz,',
08:46clojurebotEOF while reading
08:46Chousukejdz: why would you want to quote whitespace? :)
08:46jdzcomma is not whitespace :/
08:46Chousukeyes it is.
08:46Chousukein clojure :P
08:46jdzi want a symbol whose name is ","
08:46Chousuke(symbol ",")
08:46jdzbut yeah, you have a point
08:47Chousukebut that's not very useful
08:48ChouserLauJensen: underscores!
08:49jdzLauJensen: if i'm not a domain expert, i don't have a slightest clue whether #(* (/ (- %1 %2) (- %3 %2)) %4) is correct or not
08:50jdzand you can't tell just by looking at it, too
08:50rhickeyunderscores - ick
08:50jdzat least you won't after 2 weeks
08:52jdzLauJensen: in your code, whenever i see #(), i see something that derserves a name. really.
08:52Chouserthe use of #() in axis-seqs looks ok to me
08:53rhickeylots o swaps in there
08:54jdzChouser: well, i might have swept some legit cases under the rug here. but i already mentioned the disclaimer ;)
08:54ChouserLauJensen: what it draws is pretty. Nice idea for a blog post!
08:58Chouserrhickey: thanks for ->> Now hiredman can quit doing (-> ... partial ... partial ... partial) :-)
08:58crioscome back. what happened to the web freenode chat
08:58rhickeyhah
08:59rhickeyLauJensen: yes, nice idea
09:00rhickey,(doc ->>)
09:00clojurebotIt's greek to me.
09:02LauJensenChouser, rhickey, thanks guys
09:03ChouserLauJensen: You could use (while ...) instead of recur in animate
09:03LauJensenChouser: What benefits would that give me ?
09:04Chouserit makes it more obvious that you've got an imperative loop doing mutation.
09:06LauJensenI guess that's true. Doesn't affect performance or anything like that ?
09:07Chouser,(macroexpand-1 '(while foo (blah) (blah)))
09:07clojurebot(clojure.core/loop [] (clojure.core/when foo (blah) (blah) (recur)))
09:07Chousernope, it's the same thing. :-)
09:08LauJensenAh ok
09:09LauJensenI think I'll hang on to your idea for my "A tribute to Chris Houser" post :)
09:18LauJensenrhickey: your line 'lots o swaps in there', was a comment on my code, would you have modelled it differently? how/why
09:37ChouserLauJensen: nothing about the problem requires mutable state (other than the canvas itself), and as you said the purpose of the atoms are to avoid holding the seq heads, right?
09:38LauJensenyea
09:38LauJensenPut would it have been better to go with something other than atoms to get rid of the head?
09:39Chouserso it's likely there is a way to solve the head-holding problem without resorting to mutable state
09:39LauJensenhmm
09:41Chouserif spawns were a fn instead of a seq, then in 'animate' you could (apply map vector (spawns)) to get a single lazy seq of your "frames"
09:42Chouserthen consume that seq using a normal non-head-holding thing (map, for, whatever)
09:44Chouserbasically just push those lazy seqs further down into your code instead of trailing off at 'spawns'
09:45ChouserI understand you have swing at the other end trying to push side-effects and statefulness up, so there's definite tension there.
09:45LauJensenOk, I'll try to model it that was for my 3D Lorenz attractor - I have a hard time visualising that last map though
09:46Chouserit's actually perfectly legitimate to draw on a swing canvas without waiting for a paint call
09:47Chouserdoing it that way would allow you to pass in the data to be drawn rather than having it sitting is some global state for the paint method to fetch.
09:48LauJensenBut that would spoil the animation effect wouldn't it ?
09:48Chouserhow?
09:49criosFossi, were you saying that clojure could *really* replace java in any domain application ?
09:49LauJensenI think I misunderstood you, can you explain ? :)
09:50ChouserLauJensen: http://gist.github.com/40012
09:51Chouserthere is code that "animates" drawing into a Frame without any mutable state. It doesn't even use proxy.
09:52LauJensenOh I see
09:53ChouserIt also doesn't do any of that hard math stuff. :-)
09:54LauJensenWould make for a good blog post Chris :)
09:54Chouserit was a good blog post, if I may say so myself. ;-)
09:54LauJensen( and don't call that sorry presentation you did way back when a 'blogpost' )
09:55Chouseroh
09:55Chouseryes, I seem to remember you complaining about it at the time.
09:55LauJensenhehe, I'm going back now to find it
09:55LauJensenoh yes now I see... it's awful
09:55LauJensenYou really should delete that
09:56crios_In web applications I don't really expect that for generic day-to-day e-business applications will be an urgence to migrate towards a multicore approach, because: 1) latency on the network hides speed on the multicore servers 2) applications that do needed more computitionally power were and are written with distribuited architectural designs 3) java web frameworks handle any http request into an each own thread. The cost to migr
09:57Chousercrios_: cut off at "cost to migr"
09:57crios_where do you really believe that clojure have a chance to become a mainstream language?
09:58crios_Chouser, I think there is a cost to migrate a well oiled java team to a new language + frameworks
09:58licoresseWhat is the cost? When you're fed up with the verbosity of Java?
09:59Chousercrios_: I think some teams (perhaps mostly new teams?) will find the ability to leverage high-core-count processors with less ceremony than it takes to handle 1 core in java now to be attractive.
10:00crios_licoresse: Do you really think that a less verbose language has higher business value? how COBOL's life fit here?
10:00Chousersurely many people will never find Clojure attractive. It's sad but I believe it.
10:01licoressecrios_: No, not the way YOU put it, put I am sure you can see other ways
10:02licoressehopefully the pointy-hair-boss-generation is going to die out, haha
10:02ChouserI think that relational databases as a one-size-fits-all solution is on the decline, and as apps get more hands-on with their data, manipulating stuff in memory from multiple threads simultaneously will start to sound like a better and better idea.
10:02licoressethe ones that are scared to shit of new ideas
10:02LauJensenlicoresse: They don't die, they become the bosses of the new bosses :)
10:03licoresse:)
10:03Chouserbut without better tools to handle that concurrency, though, it's still a dangerous proposition. Clojure can help address that danger.
10:04licoressewell, what is another 25 years of stagnation
10:04crios_licoresse: you're doing philosophy here :) I was just questioning if the mere "less-verbosity" Clojure language is really of any business value. I think not.
10:05ChouserI think ruby became so popular largely because of rails, which was built and became popular largely because of ruby's strength in meta-programming (using block iterators, etc.) compared to perl, php, etc. I think Clojure's strong in that regard even if you ignore its strength in speed and concurrency.
10:05licoresseof course not, but clojure is about *more* than verbosity, seriously...
10:06licoressewhat do I know, I am just getting excited, as I did when I first discovered Smalltalk
10:07licoresseoh man, I was excited then, turtles all the way down... hehe
10:09crios_I'm too excited. But we work in very real teams and corporations :)
10:09crios_and I'd like to see where the clojure language could fit there
10:09ChouserI'm such a lisp weenie now. I look at code in some syntaxy language and it just hurts. :-(
10:10licoresselisp weenie?
10:10Chouserwas my definition there too vague?
10:11LauJensencrios, ever line of code technically represents the posibility for a bug and therefor a maintenance cost. What would you rather maintain, 25.000 lines of C or 3000 lines of Clojure? Calculate a businesscase and get back to me
10:11crios_I saw some web example written in clojure. It does not seem more readable than a scriplet jsp
10:11licoresseno, I was just surprised
10:11crios_"scripleted"
10:11crios_the code have to be readable
10:11Chouserlicoresse: ah. well, "zealot" doesn't quite fit because I don't feel the need to convert someone if they're happy where they are.
10:12crios_see here: http://jng.imagine27.com/articles/2009-09-12-122605_pong_in_clojure.html
10:12crios_To be honest, this is just plain old spaghetti code! :)
10:12Chouserlicoresse: and "aficionado" sounds pretentious and doesn't convey the slight negative connotation I was after.
10:12crios_see the actionPerformed function
10:13licoressehmm
10:13Chousercrios_: yeah, that's not particularly idiomatic clojure. too much state
10:13crios_a java junior should migrate to clojure? never on my team! :D
10:13licoressethere are @ all over the place
10:14crios_you, for me, are power user, examples to follow if I want to become a clojure developer
10:14licoresseChouser: personally, I don't mind aficionado
10:14licoresseI am already using a mac, so per def. I am a zealot
10:14licoresse(shit)
10:15crios_if your code is not so readable , how do I, a wannabe clojure student :), can have stimulus?
10:15licoresseI cannot see why it would be harder to learn a lisp, than to learn something algoish
10:16Chouserlicoresse: my point was that I have a new barrier between me and learning a new language. I used to accept I would have to learn a quirky syntax and even looked forward to it to some extent. Now I'd just rather not. I'm not sure that's a positive development for me.
10:16licoresseChouser: You've come to an end point. There is still something beyond, but you don't need it right now
10:17licoresseI think that is perfectly ok
10:18licoresseI need to go pick up the kids, later folks
10:18crios_bye
10:19crios_So, Clojure could replace java (in the mainstream) because databases are going "in the cloud", and because writting a web application with it is much more (funny and) easy? Be honest, people :)
10:21stuartsierraHonest? No Lisp-derivative will ever go mainstream.
10:21LauJensenAsk the question "How could it not" ? Java isn't exactly 'up to date'
10:21crios_[I've no FUD intent, clearly. Just trying to understand you point of view]
10:21crios_[your]
10:22Chousercrios_: I'm mearly hopeful that Clojure could become sufficiently popular, not by any means convinced that it will.
10:23crios_I know (well) LauJensen. But COBOL, too, is decades which is "to be dying". But it was the best language for the business
10:23crios_thank you Chouser. So I'm not an alien :)
10:23dnolen-recChouser: you don't think it's sufficiently popular already? For example I used love reading the twitter search feed on Clojure. Now there's too many mnetions to really bother :)
10:24Chouserwhere "sufficiently popular" is not "more popular than java" or "the favorite language of more programmers than C#" but simply "widely used enough that everyone who wants to can be earn a living using it"
10:24crios_+1 Chouser
10:25crios_Our field was (and is) full of buzz words, and "silver bullets" news
10:25Chouserdnolen-rec: nope, not quite yet. growing pains are inevitable, but my boss still rolls his eyes when I mention it. We've got to get past that. :-)
10:25adityoalready making a *living* out of Clojure
10:25Chouseradityo: you are? congrats!
10:25dnolen-recChouser: you made you remark just as entered mine. That is a good benchmark: that you can use at your job with noone blinking an eye.
10:26crios_adityo: really?
10:26Chousernote that my definition there includes rhickey making a living using Clojure, since he wants to. We're not there yet. :-)
10:26adityoChouser: convinced management to use Clojure instead of Common Lisp
10:27adityoyet to launch our products but development is on
10:27crios_adityo: in what application domains? What kind of software do you develope?
10:27adityomainly web dev
10:28crios_entirely written in clojure?
10:28Chouseradityo: fantastic.
10:28adityodeveloping the backend for a news portal, using Clojure postgres and Java
10:29crios_your clojure code is written by ex-java developers or by ex-common lisp coders?
10:29dnolen-reccrios_: I think web dev and clojure are a really good fit. I actually wanted to use it on an open source project, but just not yet a wise option. perhaps another benchmark.
10:29adityoi am a ex common lisper..
10:30crios_so adityo didn't you migrate java developers to clojure, do you?
10:31adityoactually no..but clojure has been a compelling case to prove to management to have Lisp like languages in an 'Enterprise' envirionment
10:32rsynnottI'm not sure that the primary goal of a language should necessarily be to be popular....
10:33crios_your management was already accustomed to that, being formerly accustomed to Common Lisp. Yet I see its value :)
10:34crios_rsynnott: of course not :) Just trying to be honest on its *real-business* applications
10:35crios_dnolen-rec: why was not clojure the right choice?
10:35rsynnottI think it has applications there
10:35rsynnottnot necessarily terribly widespread applications
10:35rsynnott(if nothing else, the majority, possibly the vast majority, of all commercial programmers are idiots)
10:36crios_so the web2 / web-economy / web society is written by idiots? :D
10:37crios_rsynnott: "there"? where precisely? Again, I'm just trying to understand
10:38rsynnottI think it has applications commercially
10:38dnolen-reccrios_: just that not enough open source devs who know Clojure. so we picked Python. it's just our backend tho. about 10% of the code base. Our project is almost entirely JavaScript. Soon as that's ironed out, I'd like to reimplement that 10% in Clojure for our own internal use :D
10:38rsynnott"so the web2 / web-economy / web society is written by idiots?" - broadly speaking, yes
10:38rsynnottthe average quality of commercial code is STUNNINGLY low
10:39rsynnottdnolen-rec: no-one's gotten around to writing a parenscript equivalent, yet? :)
10:40dnolen-recrsynnott: There was some work on it on the list, but it's only half finished as far I could tell. lots of real usage edge cases that were broken.
10:42rsynnottcrios_: in particular, there is a lot of copy-and-paste coding out there; people writing stuff without actually understanding what they're doing
10:42rsynnottyou don't need comet if you're only talking TO the server
10:43rsynnottif you're sending data to the CLIENT, then you need comet
10:43dnolen-recrsynnott: for live debugging. Like Symbolic web.
10:43rsynnottah :)
10:43crios_you're right rsynnott
10:43crios_Plus, add cost-cut operations
10:44crios_where junior developers replace senior
10:44sproingiehey i'm learning clojure, and have a little familiarity with a lot of languages, and i discovered multimethods, but noticed there wasn't much way to combine them
10:44sproingieis there some common idiom in place to simulate call-next-method?
10:44rsynnottactually, comet is a perfect use-case for clojure; the only decent comet server impls are in java, but obviously no-one really wants to write an app backend in HORRIBLE JAVA :)
10:44dnolen-recrsynnott: yup.
10:44dnolen-recsproingle: have you looked at get-method?
10:45dnolen-recGoogle should be writing Wave in Clojure.
10:45rsynnott(replacing an older erlang-proxying-to-python comet system)
10:45sproingiednolen-rec: i'm not sure how i'd use it
10:46sproingieget-method appears to be single-dispatch
10:46dnolen-recsproingle: if you dispatching on type you can look at the parent of the current type. and find the method for that type.
10:46rsynnottcrios_: of course, many senior developers are also incompetent :)
10:47sproingiesure, but i'm not always certain which parameter the next method dispatches on
10:47crios_anyone here? ;-)
10:47rsynnott(one great downside to these amazing fast computers we now have, with access to the internet for copy-and-pasting, is that it is often possible for incompetents to be successful)
10:47Fossiword
10:48sproingiei guess i could go through each one in order sort of like clos. i'm not intimately familiar with how clos resolves them either
10:48crios_by the way, about the "cloud" buzzing: http://java.sun.com/javaone/2009/articles/rockstar_click.jsp
10:49tmountain~logs
10:49clojurebotlogs is http://clojure-log.n01se.net/
10:49crios_"Lose its hype, lose its fuzziness, and split into a couple of well-defined camps, e.g., render farms; Google/Yahoo search-farms; Amazon-style EC2; plus one or two competitors to Amazon. "
10:49crios_I think so, too
10:49dnolen-recsproingle: hmmm, if you want CLOS like behavior I think mikel did some work on a library called generic functions
10:50dnolen-recsproingle: http://code.google.com/p/explorersguild/wiki/XGModelAndGF
10:50rsynnottto a large extent, the cloud thing is just marketing
10:50sproingiednolen-rec: ooh looks exactly like what i'm looking for, thanks :)
10:51dnolen-recnp
10:52crios_rsynnott, you see copy&paste as bad, yet it allowed a great sharing of knowledge. In the first days all HTML stuff was "source code available". It endorsed the web sites diffusion - IMHO
10:53crios_Today, programming as "code snipplets combination" seems to be the future! I don't like that, too
10:54rsynnottvery dangerous, though; it allows people to write software which SEEMS to work, without understanding what they're doing
10:54crios_more people, lesser quality
10:55rsynnottI suspect the Great Recession is driving up the quality if programmers to an extent by reducing the size of the job market
10:55crios_so, your question was: can this "idiots" people really understand clojure?
10:55rsynnottI suspect that they might have more trouble with it than, say, php or java
10:55rsynnottwhich is no bad thing :)
10:56crios_;)
10:59crios_adityo: is it yours? :O http://ericlavigne.wordpress.com/2008/12/28/using-postgresql-with-compojure/
11:00Chousershouldn't functional code be *more* amenable to copy&paste than procedural code?
11:02rsynnottin general, people who do copy-and-paste programmng will not learn new things :)
11:02crios_Chouser: good question. Maybe yes . Expecially if uses pure functions
11:02rsynnottif clojure were ever to become very big in industry, the same problem would no doubt emerge
11:02rsynnott(as any technology gets more mainstream the average user usually gets stupider)
11:03rsynnottthough for whatever reason some are a little resistant; python for instance seems to be extremely offputting to the copy-and-paste crowd
11:04crios_in general, it depends on how the useful code is refactored into imported libraries
11:04crios_I mean, fewer code to copy, if it is into a library
11:12crios_However, coming to the "concurrency" question: I think the real urge, if it has to be, lies on client applications, not server ones. The "multicore revolution" is into the customer market, not in the server. What do you think? Thus Clojure whould matter when writting for example a Swing application
11:13Chousercrios_: will servers not have multiple cores?
11:14tmountaincrios_: I think it matters anywhere that there's more than one core
11:14crios_well, multiprocessor servers are a news?
11:15tmountaincrios_: with all the map/reduce fanfare as of late. the divide and conquer approach pretty much guarantees a lot of parallelism on the backend.
11:17crios_just for fun, an example of an old multiprocessor: http://3.bp.blogspot.com/__QeUMay1P8w/Se2Jtk7R0rI/AAAAAAAABX8/GIRtzZjzLIQ/s1600-h/multiprocessor.jpg
11:17crios_tmountain: could you explain better the "fanfare" part?
11:21tmountaingoogle's map/reduce framework, yahoo's hadoop, amazon's data crunching service, etc... they've all gained the attention of startup companies across the map as efficient ways of working with large amounts of data
11:21tmountainof course, you could just use one of the existing frameworks out there to do the job for you
11:22hamza`hey guys, how would you transform while(true){ read from socket after a while break} into clojure. i need to read from socket for a while and when conditions are met stop reading?
11:22tmountainbut a lot of projects demand a higher level of customization
11:23crios_tmountain: I understand. So the hype on server side is into the "distributed" processing, maybe?
11:25tmountaintmountain: yeah, that's exactly what I'm saying. a lot of burgeoning companies want to do things like recommendation systems (i.e., netflix five star ratings) or other data intensive tasks
11:25tmountainoops, refere'd to myself there :p
11:26tmountainhamza`: have a look at clojure.contrib.server-socket
11:26tmountainhamza`: probably a good starting point
11:26tmountaincrios_: all that kind of stuff lends itself to parallel processing in a big way
11:27crios_tmountain: mmm still I believe they'll stay just "business niche"
11:27crios_at least, in short time terms
11:27hamza`tmountain: thx but what i am reading from is not an actual socket. but since it is socket like thats why i refered it a socket my bad.
11:28hamza`i am going to be reading from a packet capture lib when i have enough packets i want to exit.
11:28hamza`loop and process them.
11:30tmountainhamza`: http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#Looping_and_Iterating
11:30tmountainhamza`: a loop / when / recur construct would probably do what you want
11:34crios_I have to go. Thank you all for the very interesting discussion.
11:34crios_ciao
11:46Chouserhamza`: (take n (repeatedly #(read-from-socket))) may work, depending on your performance requirements
11:53mtm,(int (+ 23/9 1/2))
11:53clojurebot3
12:01arohnerhaving hashmaps and the HOF map share the same name is getting annoying
12:02arohnerI want to run map on the keys of a map, and I keep saying map
12:02Chouserarohner: yes, it's unfortunate
12:03ChouserYou can say hash-map and be inaccurate, or IPersistentMap and be wordy, or clojure.core/map and be wordy the other way ... :-/
12:03mccraigis there a clojure api for globbing filenames from a directory ?
12:04Chousermccraig: file-seq might be close to what you want
12:05Chouseror (filter #(re-find #"\.txt" (.getName %)) (-> "/tmp" java.io.File. .listFiles))
12:08ordnungswidrigChouser: #"\.txt$" you mean?
12:08Chouserordnungswidrig: sure
12:08ordnungswidrigDidn't mean to nitpick.
12:08Chouser:-) np
12:09Chouserif we're not willing to nitpick, we're in the wrong field.
12:09ordnungswidrigyeah, fp nitpicking
12:09ordnungswidrigbettern than oo design
12:10ordnungswidrigI wondered why I have such strange 404 requests in my clojure console. But only when working at home.
12:11ordnungswidrigActually it was my android phone which tried to reach a funambol server at localhost:8080 only when my wlan.
12:11ordnungswidrig*doh*
12:13mccraigChouser: that should do fine. thx
12:13ordnungswidrigemacs users here?
12:13ordnungswidrig(and awake?)
12:13manic12yeah
12:13manic12sorta awake
12:16ordnungswidrigmanic12: perhaps you can help me. I use paredit but the matching open paren is only highlighted if the cursor is _behind_ the closing paren -- not on the paren.
12:17manic12whatever mode I'm using, after you type the closing paren it highlights the opening one
12:20ordnungswidrighmm. thanks.
12:20manic12sorry i couldn't have been more help
12:25ordnungswidrigmanic12: another one. How can I disable the current line highlighting. I don't remember the option / face / variable
12:26manic12i dunno that one, because mine does not do it by default
12:27stuartsierraordnungswidrig: turn off hl-line-mode
12:27ordnungswidrigstuartsierra: thax.
12:31mtmglobal-hl-line-mode will toggle it for all buffers
12:31LauJensenIs there a simple way to get something like "2009-09-11" by subtracting 14 days from today, without involving Joda ?
12:35stuartsierraWeeeel, (.getTime (Date.)) gives you current time as a long, then you could subtract equivalent of 14 days, get another Date, then use java.sql.Date to format it.
12:39stuartsierraor use java.util.Calendar, which is even more complicated
12:40manic12get-univeral-time...d'oh
13:49abedraare there any geolocation libraries available for clojure yet?
13:52dysingerHey our clojure projects are getting more and more sophisticated and we noticed some code we depend on depends on asm (by way of maven dependencies)
13:52dysingerthe asm version is 3.1
13:52dysingerwhat's the version of clojure ?
13:52ddonnellabedra: can you be more specific?
13:52dysingerit's just inlined into the clojure repo right ?
13:52abedraddonnell: i'm looking to turn addresses into geocodes to draw points on a google map
13:54ddonnellabedra: is there a particular service you want to use for the geocoding?
13:55abedraddonnell: not in particular, I was just wondering if anyone had started down this path
13:55abedraddonnell: if not, I will just figure it out
13:57ddonnellabedra: i don't know of any clojure specific ones, but it's pretty easy to use the api's from places like google
13:58emacsenIs there a generic function to take a string and return it as a number?
13:58emacsenthere must be, since the repl does it...
14:00Chouser,(read-string "45M")
14:00clojurebot45M
14:01emacsenheh- good call :)
14:01Chousermight need *read-eval* false
14:07emacsenChouser: here's a more complex question... I understand how to dispatch my own functions, but is there a way to control distpatch of str?
14:09andyspabedra: the Fmaps HTTP geocoder is quite simple
14:09andyspdoesn't really nead a wrapper lib
14:09andysp*GMaps that is
14:09emacsenandysp: geocoder?
14:09Chouseremacsen: you've got a couple options
14:09emacsenandysp: use geocommons :)
14:10Chouseremacsen: (defmulti my-str ...) (binding [str my-str] ...)
14:11emacsenChouser: right, so that's essentially my own version of str
14:11emacsenno?
14:12Chouser(proxy [Object] (toString [] ...))
14:12Chouseror manipulate your namespace 'refers' so that 'str' is your own rather than clojure.core/str
14:13Chouserthat's all I can think of.
14:13emacsenFair nuff
14:13emacsenthx
14:13Chouseroh, print-method is a multimethod, so if that's why you want to tweak it, you can do it at that level
14:13emacsenChouser: basically I want to be able to print my struct (which I know is just a map) in a specific way
14:14emacsenthat's the reason for all this
14:14emacsenandysp_: did you get my previous suggestion?
14:15Chouseremacsen: ah, then print-method will be perfect
14:15emacsencool thanks!
14:17Chouser(defmethod print-method :my-thing [o w] (.write w (str "#<this is my thing>")))
14:17Chouser#^{:type :my-thing} ['whatever] ; prints: #<this is my thing>
14:18emacsenthx
14:18Chousernp
14:25hamza`hey guys, i am trying to create a list of string such as 12.1 12.2 12.3 ... to 12.254 using (apply vector (interleave (repeat "12.") (range 1 255))) can i turn this in to a vector os strings?
14:27Chouser,(vec (map #(str "12." %) (range 1 12)))
14:27clojurebot["12.1" "12.2" "12.3" "12.4" "12.5" "12.6" "12.7" "12.8" "12.9" "12.10" "12.11"]
14:28hamza`lol thx, much shorter than what i was thinking.
14:28hamza`(map str (partition 2 (apply vector (interleave (repeat "12.") (range 1 255)))))
14:29Chouserright. replace str with (partial apply str)
14:30Chouseror #(apply str %)
14:30Chouserand use vec instead of apply vector
14:30hamza`kk thx, yours is much more readable
14:30Chouseryours might be required depending on specifics. :-)
14:32licoresse,apply
14:32clojurebot#<core$apply__3948 clojure.core$apply__3948@11b8a6b>
14:32licoresse,(doc apply)
14:32clojurebot"([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."
14:32hamza`for each item in this list i need to call a function with side effects is it ok to use apply or map?
14:33Chouserapply won't do it. map is not for side-effects. try doseq
14:33hamza`ok
14:34Chouserif you need both the side effects and the return value -- you're probably doing something wrong. :-)
14:34Chouserbut if you still need both, you could use (doall (map ...))
14:34hamza`no, no need for return just write to disk for each and i am done
14:34licoresseso doall can be recognized as a smell
14:34licoresse?
14:35licoresse,(doc doall)
14:35clojurebot"([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."
14:36hamza`,(doc vec)
14:36clojurebot"([coll]); Creates a new vector containing the contents of coll."
14:37licoresseah, this head-retaining-thing...
14:41Chouserwell, if you want to force a lazy seq, but not do anything else (like pour it into a vector, for example) than doall is the best choice
14:41licoresseI like the analogy
14:42Chouserand I suppose lazy seqs with side effects aren't inherently wrong, just a little fragile.
14:47hamza`on side effects i have a question i have a ref that holds a list of customers when a new customer is added ref is changes in a dosync block and i would like to write the new structure to disk. i read somewhere that side effects should not be in transactions is this bad desing?
14:48Chouseryour design is fine except for the io in dosync
14:48technomancyhamza`: if you set it off in an agent, it will only write if the transaction succeeds
14:48technomancybut it will *not* get you a guaranteed atomic commit-and-write like a real RDBMS
14:49Chouseror you could put a watcher on the ref
14:49technomancyeven better
14:50hamza`i am not looking for acid properties i just don't want more than 1 thread write the file and corrupt it. so a watcher is called when transaction succeds?
14:51hamza`and what about checking if something is in the ref or not does that belong in the transaction or should i just use ref-set in dosync?
14:52Chouserhamza`: look at add-watch
14:52ChouserI don't understand your second question. You can look at the contents of a single ref from anywhere at any time
14:54hamza`no i mean say that i have set of values. i need to check the set and only add stuff to it if it does not already contain it. now can i in a dosync check if set contains the element and if not create a new set and update ref. of check outside the transaction and just set ref inside the transaction?
14:54hamza`i mean which one is more idiomatic?
14:56Chouserprobably do it all inside a dosync. I think dosync is quite cheap until you start setting things.
14:56Chouserdon't use ref-set to update it though, use alter
14:57hamza`performence reasons or something else?
14:57hamza`,(doc alter)
14:57clojurebot"([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref."
14:57Chousersomething else. :-) using alter allows you to apply a pure function to state, transitioning it from previous to next state.
14:57Chouserthe future is a function of the past [or at least should be]
14:58Chouserref-set is a blunt instrument, indicating to someone reading your code that you don't care what the previous value was, which is not true when adding an item to a set.
14:59hamza`ok, now i get it.
15:16gcvI could use a little help with macro scope rules:
15:16gcv(let [f1 #(inc %)] (defmacro m1 [x] `(~f1 ~x)))
15:16gcvThen: (m1 12) throws an extremely unhelpful exception.
15:17gcvThis idiom works perfectly in Common Lisp.
15:18ChouserI assume that's a simplification?
15:18gcvyes :) but the general idea is to lexically capture a function inside a macroexpansion.
15:19Chouserit seems we use to run into this a lot, but haven't in a while. I also thought we used to get a nicer error message.
15:19Chouser...trying to remember...
15:20sgtarrrun into what?
15:20Chouserthis type of question
15:21sgtarroh
15:21Chouseryes, ok, it has to do with functions not being printable readably.
15:23stuartsierraI would write (defmacro m1 [x] `(let [f# (fn [y#] (inc y#))] (f# ~x)))
15:23Chouseror put the fn in var instead of in a local
15:24gcvalas, this is where simplification bites --- this is for a macro defining macro, where the outer accepts an arbitrary function parameter
15:25Chousercan you not just insert the form of that function?
15:26Chouseroh, I see -- it may itself be a local referring to an anonymous fn rather than the anonymous fn form itself?
15:27gcvlive code: http://paste.lisp.org/display/87728
15:27gcvit's broken in a subtle way right now
15:29gcvif you try to use with-db-env in an external namespace which does not import the functions db-open and db-close, the macroexpansion refers to unavailable symbols.
15:29Chouserthe auto-gen-sym won't work across multiple `
15:29gcvinteresting, so that's clearly another problem
15:30gcvactually, the code does work, as long as all symbols are visible
15:30Chouserreally! hm.
15:31Chouser,`(foo var# `var#)
15:31clojurebot(sandbox/foo var__4024__auto__ (quote sandbox/var__4023__auto__))
15:31Chouserah, neat!
15:31Chouser`(foo var# `~var#)
15:31Chouser,`(foo var# `~var#)
15:31clojurebot(sandbox/foo var__4028__auto__ var__4028__auto__)
15:32Chouseryou're right! My experience with macro-writing-macros is clearly quite shallow...
15:33gcvanyhow, I've been trying to get around this scoping problem by making sure that arguments to def-with-db-macro get captured for the inner macro. I can guarantee that def-with-db-macro will always have the needed symbols visible.
15:33stuartsierraDon't know if this helps, but I've found macro-writing-macros to be easier by avoiding backquote altogether and creating output forms like (list 'foo ...)
15:34gcvstuartsierra: it's worth a shot, but I think my problem is in scoping rules
15:34licoresseinteresting..
15:34Chousergcv: you might try using ~`~open-fn instead of ~'~open-fn
15:35Chouserno, scratch that.
15:36gcvthe thing about print readably functions... when I try something like my original example in CL, I don't need to (setq *print-readably* t) for it to work
15:37gcvbesides, I'm pretty sure it still works even if the function is a closure, and you can't reliably print-readably a closure in CL or in Clojure AFAIK
15:37gcv^is a closure^closes over something
15:38ChouserI'm out on a limb here, but I think clojure may go through a print step to support AOT compilation to bytecode that CL doesn't need to do.
15:38stuartsierraBut in CL #'(lambda ...) is considered a literal.
15:39Chouseranother thought: I think you want the macro produced by def-with-db-macro to have a ` in it, so that symbols passed in are resolved in the ns were def-with-db-macro is called
15:40Chouserbut I don't even know if that's possible right now since ` is not a shortcut for any special form, but does its work at read-time.
15:40ChouserI think there are plans to change that
15:40technomancy` doesn't expand to quasiquote?
15:41Chousertechnomancy: it's called syntax-quote in clojure, and no I don't think so.
15:41Chouser,''5
15:41clojurebot(quote 5)
15:41Chouser,'`5
15:41clojurebot5
15:41gcvsorry, that went over my head. quasiquote?
15:42lpetithi all
15:42Chouserone could imagine a ` that at read-time expands to (syntax-quote ...) just like ' reads as (quote ...)
15:43Chouserbut that's not what happens now
15:45gcvvery interesting
15:48gcvthanks for the answers, guys. I'll hammer at this for a little while more, but I'll probably end up just writing out all with-db-* macros by hand for now
15:48Chousergcv: a very intersting problem, thanks for sharing.
15:49Chousergcv: it may be worth posting to the google group -- wider audience and more available time for thought
15:49stuartsierraI think you can't refer to an anonymous function in a macroexpansion.
15:49stuartsierraBecause it doesn't have a literal representation.
15:49stuartsierraYou can only refer to a locally-bound symbol.
15:49Chouserit would be intruiging if the fact that ` does the namespace qualification at read time means that some kinds of macros can't be produced from other macros.
16:06lisppaste8Chouser pasted "macro-defining macros across namespaces" at http://paste.lisp.org/display/87734
16:08Chousergcv: that might help, but the problem in your case is that instead of a literal foo, you take an argument that may not be a simple symbol. You have one example where it's an anon fn form.
16:09gcvChouser: that does help. thanks! but you're also right about the fn form making things worse. :(
16:09Chouserso rather than a simple-minded (symbol ...) call, I think you'd have to walk the form qualifying every symbol you find
16:09gcvI'm composing a message to the Google group
16:10Chouser...which is essentially what ` does, but you can't use that code because it's tied to read-time which is too early for you.
16:10Chouserall of which is separate from your original question, btw. :-)
16:10gcvthis particular use isn't worth the effort, either. I don't like the boilerplate with-db* macros I'll end up with
16:11ChouserI mean, your original simplified form demonstrated a different issue.
16:11gcvwell, it's a discussion of solving the problem which bit me in the first place
16:11gcvthat was just an attempted workaround
16:11Chouserok, sure.
16:11gcvactually, looking at this message I'm writing, I'm not sure which of the two to attack
16:11Chouserfwiw, the idea of makeing with-open more general has come up before. I think there's a non-macro solution in the works.
16:12hiredman:|
16:12hiredmanwe just need scopes!
16:12hiredman~scopes
16:12clojurebotNo entiendo
16:12hiredman~scope
16:12clojurebotscope is at http://paste.lisp.org/display/73838
16:12gcvhiredman: scopes! if only you knew how badly this code I'm writing could use those
16:12Chouserhm. indeed.
16:13hiredmangcv: I have an implementation that worked (last time I used it, months ago)
16:13gcvhiredman: link?
16:13hiredmanjust a second
16:14gcvfwiw, I hacked around needing scopes for the time being, but I welcome the opportunity to make my code more useable
16:14hiredmanhttp://github.com/hiredman/clojurebot/blob/90fd15bec80bacd7c41cca41c971279587aa25ae/hiredman/horizon.clj
16:14hiredmancalled it horizon instead of scope
16:15hiredmanthe only real testing I did was to make sure rhickey's scope example worked
16:17gcvkinda cool
16:18hiredmanit's nice for resouce management
16:18gcvI'm guessing the official implementation wouldn't use dynamic variables for state
16:18hiredmanI have no idea
16:18gcvResource management is precisely what I need it for. I made a lazy-seq based abstraction for database cursors, and ended up with the problem of cleaning them up when they aren't completely consumed.
16:19hiredmanyou can definitely get into trouble when combining dynamic+lazy
16:21hiredmanbut with scope(horizon) you can have your database cursor creating function register it's clean up action in the surrounding scope, and it will throw an exception if called outside of a scope
16:23dhazais the clojure wikibooks.org page a good repo for all the clojure PDFs/ebooks out there?
16:23dhazafreely licensed ones, that is
16:26hiredmanI don't know that there are any
16:30criosa maybe stupid question, out of curiosity: in Lisp is there an automatic memory management?
16:30mDuffcrios, yes
16:30gcvcrios: Lisp is the first language to ever have had a garbage collector. It was written sometime before 1959.
16:31criosyes. I'm reading "Coders at work", and I was assuring to have well understood
16:31hiredmancrios: gc has been called part of the dna of lisp
16:32criosAfter having worked in Lisp and C, when turned to Java it felt a "return to Lisp"
16:33criosit says: "memory management. that functions felt more like functions that subroutines"
16:33crios[he says]
16:33gcvI haven't read the book yet. Is this the Guy Steele interview?
16:34sproingiewhen functions aren't even first-class objects, i can't see how it's in any form like a return to lisp
16:34criospeter seibel: http://www.amazon.com/Coders-at-Work-Peter-Seibel/dp/1430219483
16:34sproingieseeing gc as the defining characteristic of lisp is about as warped as it gets
16:35gcvsproingie: it's a common view among a certain generation of hackers.
16:35gcvI had a professor in college who called Java "a weak reimplementation of the semantics of Lisp."
16:35sproingieamong those whos first exposure to gc was from lisp
16:35sproingieand to some it would appear, their only
16:35gcvbasically yeah
16:35hiredman*cough*
16:36criossproingie: "there was much more enforced modularity to it. it's always tempting to throw in a goto c code just because it's easy"
16:36sproingiehuh
16:36sproingiei've done C for more than a decade, never felt "tempted" to use a goto
16:36criosjava enforce more than C to write a structured code
16:37hiredmanif you subscribe to the idea that all languages are asymptoticaly approaching lisp, then you could say just about any laungage is "a weak reimplementation of the semantics of Lisp"
16:37crios:) just reporting the thought of Emacs / Netscape hacker
16:37dhazagotos can make sense if you want to ensure a block of code executes after a complex code chain in a function
16:37sproingiehiredman: subtitle: phil greenspun falls into the turing tarpit
16:38sproingieforward-only gotos aren't so bad in C. mostly because C doesn't have a 'break LABEL' syntax
16:39dhazaright. ive very rarely seen goto abused in actual code
16:39dhazaie not demonstration code of why goto is bad
16:39sproingiei've seen it to redo a loop body which i tend to think is abuse
16:40criosin java, you can "goto" just to exit loops. But also breaks and continue should be avoided
16:40sproingiebut it was in seriously performance-critical code
16:40sproingieso i'd probably have done the same
16:40gcvgoto is pretty essential in C for cleaning up resources
16:40criosok ok, no flame "goto" war now - the times are gone :)
16:40sproingierule of thumb is you should at least be able to keep the goto and the target label on the same screen
16:41criosinteresting
16:41criosin order to enhance its readability
16:41ordnungswidrigsproingie: that rule might work on a 12in terminal, not with today 30in screens
16:41sproingiegoto is a crude tool, real hackers use Duff's Device
16:41ordnungswidrigsproingie: and schwartzian transform
16:41crioswhat?
16:42sproingieschwartzian transform is decorate-sort-undecorate and comes from lisp
16:42sproingiein fact schwartz pointed that out
16:42ordnungswidrigcrios: duff's device is a manual loop unrolling using modulo operator and a case switch
16:42sproingiei like how python does it, you pass a 'key' function to sort()
16:42ordnungswidrigsproingie: schwartz is the first thing you lern doing perl
16:43ordnungswidrigdoes pyhton sort do the schwartz?
16:43sproingieit's built in
16:43sproingiesort(mylist, key=somefunc)
16:43sproingie(sorted() actually but who's counting)
16:44sproingiei do just use the schwartz actually. and yes it looks awful.
16:45sproingieyou can use a custom comparator, but it's horribly inefficient
16:45sproingieyou have to use one anyway for schwartz but at least it's a generic one
16:46sproingiedealing with collections is why i'd rather use clojure than go back to straight java :)
16:47criosordnungswidrig: maybe could use a Collections.sort and a custom Comperator
16:47cemerickah, so many new faces :-)
16:47criosor Comparable
16:47crioswho remember :D
16:48ordnungswidrigcrios: the point with schwartz is not to transform the key for every single transform.
16:49criosis the goal having an object list sorted?
16:49dhazacrios, yes, but specifically when the comparison takes a long time to compute
16:50ordnungswidrigcrios: so schwartz is about caching the result of the key-extraction.
16:50dhazaits a much fancier name than what it actually does
16:50criosmmm "The Schwartzian Transform is notable in that it does not use named temporary arrays."
16:51crioshttp://en.wikipedia.org/wiki/Schwartzian_transform
16:52ordnungswidrigdhaza: I think it's fameous because it's idiomatic perl. Don't sort without the schwartz :-)
16:53crios"The Schwartzian Transform is a version of a Lisp idiom known as decorate-sort-undecorate, which avoids recomputing the sort keys by temporarily associating them with the input items. This approach is similar to memoization, which avoids repeating the calculation of the key corresponding to a specific input value."
16:53criosinteresting
16:54criosso clojure should support it?
16:54dhazawhy wouldnt it?
16:54dhazaits just a technique, it has little to do with the language
16:54criosyes, just noting the "memoization" outline
16:56dhazayes, it should be pretty easy to make idiomatic clojure to handle it :)
16:57dhazaare there any stats on how many people are using clojure in a production env?
17:00hiredmanhttp://www.indeed.com/jobtrends?q=+jruby%2C+groovy%2C+scala%2C+clojure groovy? seriously?
17:00dhazasome kind of joke no doubt
17:01dhazawho knows more..indeed.com or google? http://www.google.com/trends?q=jruby%2C+groovy%2C+scala%2C+clojure&amp;ctab=0&amp;geo=all&amp;date=all&amp;sort=0
17:01crioswell, maybe grails
17:01cemerickdhaza: nope, there's lots of groovy programmers out there
17:01cemerickthere's a pile of them building apps on the netbeans platform, as well.
17:01criosthe grails framework uses groovy
17:01dhazawow okay, i didnt have any sense of scale for that data...i added "ruby" to the list and that makes it much more clear about whats going on
17:03criosit seems Scala is the JVM winner :D
17:03criosoops wrong channel :P
17:03cemerickhopefully there won't be one winner again
17:04hiredmanwell, groovy is also a real word
17:04crioswhat do you mean cemerick?
17:05cemerickcrios: I want a polyglot programming world, with common platforms (jvm and clr)
17:05hiredmanI really cannot see scala "winning"
17:05crioshiredman: also scala is a real word (in Italian)
17:05cemerickSomeone on the artima thread suggested scala : java :: C++ : C, which is a pretty decent way to look at it
17:06cemerickIMO, of course
17:06ordnungswidrighttp://www.indeed.com/trendgraph/jobgraph.png?q=+jruby%2C+scala%2C+clojure%2C+haskell%2C+common+lisp
17:06hiredmanand see whatever one thinks of C++
17:06ordnungswidrighaskell plays a notable as well
17:06ordnungswidrigs/notable/\0 part/
17:07crioswell, a great part!
17:07hiredmanfirst time I've ever seen someone use a backreference in an irc regex correction
17:07dhazaso scala is a hacked together POS that worried more about backwards compatibility with a different language than sanity?
17:08hiredmanthat is harsh
17:08dhazai dont really think C++ is a POS
17:08dhazai quite like it
17:08dhazabut why they made design decisions based on C is beyond my comprehension
17:08dhazamaybe it made sense in 1992
17:08hiredmanI think scala is too tied to OOP
17:10crioswell , someone says: I'm aquainted with oop, when if I need can use a more functional approach
17:10criosScala enables this shift
17:10crios"soft shift"
17:10ordnungswidrighiredman: I'd expect any serious irc-bot to apply to regex automatically :-)
17:11ordnungswidrigPOS? What's a POS?
17:11dhazapiece of shit
17:11dhazai didnt mean it literally
17:11ordnungswidrigdhaza: :-) But hacked together get's it to the point.
17:12dhazai speak only like that as someone who had to program in half-broken C++ for a couple years
17:12dhazasymbian OS C++...does not support try/catch, but supports TRAP(), which is heavier weight and dumber than exceptions
17:12hiredmanfor example, scala-internals has had threads on and off dealing with equality and how to fix it and how broken it is, I think a lot of that problem thems from sticking the equality operator as a method onto classes
17:12dhazaof course, the reason they dont support exceptions is because they are too heavy, so its quite ironic that their "solution" makes the problem worse
17:13fsmHi, I seek comments on my clojure code, any improvements in style or to make it more idiomatic, if anyone would like to look
17:13ordnungswidrigCan't clojurebot do this yet?
17:14hiredmanclojurebot: whose job is it to ensure iodmatic coding?
17:14clojurebotthat's j0ni's job
17:14ordnungswidrigIn #haskell the bot would convert your code to point-free-style ;-)
17:14ordnungswidrigI doubt point-free would give idiomatic clojure
17:14fsmwell, my first try in a lisp/functional language
17:14fsmit's hard to know what is good or bad
17:15hiredmanordnungswidrig: clojure's functions don't have a way of querying arity information
17:15hiredmanmakes that kind of thing harder
17:15hiredmanwell, maybe not
17:16ordnungswidrigpoint-free lisp would make you go nuts because of the number of parents wouldn't it?
17:16hiredmanfirst a transform into -> style, from which point free can fall out pretty easily
17:16fsmif there are any takers, please look to http://code.google.com/p/cray/source/browse/
17:16fsmany comments are welcome
17:17hiredmanhttp://gist.github.com/184831
17:18ordnungswidrighiredman: that cries for a macro to get rid of all those "partial" forms :-)
17:18ordnungswidrighiredman: but otherwise ice
17:18fsmalso, anyone doing project euler?
17:18hiredman~euler
17:18clojureboteuler is http://clojure-euler.wikispaces.com/
17:18fsmi have completed 28 questions so far
17:19ordnungswidrighiredman: is it production code or a example you hackes together?
17:19hiredmanthat's part of clojurebot
17:19ordnungswidrighiredman: you're the one behind clojurebot, right?
17:19hiredman~ticket search Serializable
17:19clojurebot("#174: Make c.l.Keyword Serializable" "#64: GC Issue 61: \t Make Clojure datatype Java Serializable" "#174: Make c.l.Keyword Serializable" "#64: GC Issue 61: \t Make Clojure datatype Java Serializable" "#98: GC Issue 94: \t (ancestors ClassName) does not include tag ancestors of ClassName's superclasses ")
17:19hiredmanyes
17:19ordnungswidrig~mapcat
17:19clojurebotNo entiendo
17:19hiredman,(doc mapcat)
17:19clojurebot"([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection."
17:19hiredman~def mapcat
17:20ordnungswidrigtoo fast for me
17:21crioswhat is the "project euler" ?
17:21ordnungswidrighow would I model a datatype like "Either" in clojure? A list?
17:21fsmhttp://projecteuler.net
17:21fsmprogramming/math puzzles
17:21fsma fun challenge if you can resist looking up the answers
17:22hiredman,(:A {:A 1 :B 2})
17:22clojurebot1
17:22hiredman,(:B {:A 1 :B 2})
17:22clojurebot2
17:22criosfsm: oh I see, thank you.
17:22ordnungswidrighiredman: or like that.
17:22fsmbeware, it is addictive
17:24criosfsm: I was noting it!
17:25ordnungswidrighiredman: now make it a monad :-) Say, I have some functions f1,f2,f3 of signature a -> Either a bool. How would I chain them together with short-cuirciting?
17:25hiredman,(doc -?>)
17:25clojurebot"clojure.contrib.core/-?>;[[x form] [x form & forms]]; Same as clojure.core/-> but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). Examples : (-?> \"foo\" .toUpperCase (.substring 1)) returns \"OO\" (-?> nil .toUpperCase (.substring 1)) returns nil "
17:26kanakHi. I'm new to clojure, and I'm not sure how to use a function I've defined in another clj file.
17:26ordnungswidrig~def -?>
17:27crioswhat?
17:27crios,(-?> \"foo\" .toUpperCase (.substring 1))
17:27clojurebotUnsupported character: \"foo
17:27crios,(-?> "foo" .toUpperCase (.substring 1))
17:27clojurebotjava.lang.Exception: Unable to resolve symbol: -?> in this context
17:27hiredmankanak: depends on this that and the other, but you can just use load-file
17:27ordnungswidrigHow can I get the cwd of the clojure process?
17:28hiredmanugh, clojurebot is out of sync
17:28crios,(clojure.contrib.core/-?> "foo" .toUpperCase (.substring 1))
17:28clojurebotjava.lang.ClassNotFoundException: clojure.contrib.core
17:29kanak hiredman: is that different from, say using "use" or "require"?
17:29hiredmanyes
17:30hiredman,(use 'clojure.contrib.core/-?> "foo" .toUpperCase (.substring 1)) 14:33 clojurebot : java.lang.ClassNo
17:30clojurebotjava.lang.Exception: Unable to resolve symbol: .toUpperCase in this context
17:31hiredman,(use 'clojure.contrib.core)
17:31clojurebotnil
17:31hiredman,(-?> "foo" .toUpperCase)
17:31clojurebot"FOO"
17:31hiredman,(-?> nil .toUpperCase)
17:31clojurebotnil
17:31hiredman~def -?>
17:32hiredmangar
17:33criostime to go
17:33hiredmanah
17:33crios'night
17:33hiredmanno that is right
17:33kanakhiredman: can't seem to get it to work. I've got two files "simple.clj" and "common.clj" in the same directory. "simple" has a function "one-of" that I want to use in "common". Is load-file the right way to do this?
17:34hiredmankanak: depends, does each file declare it's own namespace?
17:35kanakhiredman: not yet. i'm not sure how to use namespaces either. :(
17:36hiredmanok, then load-file is fine
17:36kanakhiredman: but after i use ns to create the namespace, I can start using "use"?
17:36ordnungswidrigHow to I tell the swank repl in which directory to launch clojure?
17:36hiredman~namespace
17:36clojurebotnamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
17:37kanakthank you for your help.
17:37hiredmankanak: as long as you have the correct classpath, the correct namespaces, and the correct directory structure
17:37hiredmancorrect meaning they all reflect the information in the other two
17:38kanakthanks. do you know of any newbie friendly guide to classpaths?
17:38hiredmanclasspaths are pretty simple
17:39kanakso if i want a package a.b.c, my directory structure has to be a/b/c ? is that correct?
17:39hiredmanit's a list of directories or jars to search inside for classes
17:39hiredmanyes
17:39hiredmanand the directory a is in has to be on the classpath
17:40kanakwhere/how do i set the classpath?
17:40hiredmanvia the -cp switch to java
17:40kanakgotcha. thank you so much. let me see if i can get this to work. :)
17:40hiredmanthe -cp switch and the -jar switch are mutually exclusive, fyi
17:49fsmrandom question - would mapcat be worse than reduce concat for large collections?
17:50ordnungswidrigquick! Are http header names case sensitive?
17:52technomancyordnungswidrig: no
17:53arbschtbut many implementations care, so in practice, often yes
17:53ordnungswidrigso compojure gives me a map of headers. how do I extract one case-insentively?
17:54hiredmanrhickey: how would you feel about a patch that adds a layer of indirection between Agent and Agent.Action
17:55hiredman(headers :header (headers :HEADER))
17:56hiredmanrhickey: I'd like to make it possible to use the agent interface ontop of other executor like things
17:56hiredman(like swingutils/invokeandwait)
17:56ordnungswidrighiredman: that looks really ugly
17:57mtmhiredman: that reminds me of 'buffalo buffalo...' http://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo
17:58hiredmanordnungswidrig: I'd really hope compojure or the servlet stuff it's built on would convert everything to some consistent case
17:58ordnungswidrigmtm: *buffulo*
17:58ordnungswidrigmtm: arg. I meant "buffalo *g*"
17:58sproingiebadgher badger badger badger badgher badger badger badger badgher badger badger badger MUSHROOM MUSHROOM
17:58mtm:)
17:58hiredmanif not, it might be possible to create a ring middle ware layer that does it
17:59ordnungswidrighiredman: It doesn't as doesn't the servlet api. At least jetty doesn't. Ring middleware sounds right.
18:00ordnungswidrigme goes to bed now.... enough parentheses for today.
18:00mtmmy dreams have been in s-expressions lately...
18:08savanniI had one of those recently.
18:15rhickeyhiredman: for what purpose?
18:28cemerickrhickey: it sounds like the language summit went swimmingly. Somehow I missed that you were giving the keynote...
18:29rhickeycemerick: It went really well, great roomful as was last time. I think the keynote was appropriately provocative and well received
18:30cemerickyeah, I think just the right number of lambs were sacrificed (at least judging from the slides, etc)
18:30mtmis the video of your keynote available yet?
18:36cemerickI've been very sad that the ILC videos haven't made it off their tapes, etc.
18:40rhickeyAnd the state/identity talk from QCon
18:42cemerickrhickey: I take it you haven't heard anything about either of those?
18:42cemerickI wish the ILC had charged $500 a head or something and then had plenty to cover immediate professional dubbing of the tapes, etc.
18:43rhickeyI wouldn't hear, they just appear. I have no idea how they schedule the releases
18:43hiredmanrhickey: swingutils/invokelater and invokeandwait have the same pattern as sending off to an agent, so I would like to be able to create an Agent with Actions that swingutilities/invokelater themselves
18:43rhickeyhiredman: why does it need to be an agent?
18:44rhickeythere are lots of particular semantics of agents you might not be able to deliver on top of invokeLater
18:45hiredmanlike what?
18:47hiredmanfrom what I could tell, the guts of it is taken care of inside Action's doRun, so if that was lifted out into AAction then it could be reused
18:47rhickeyI still don't see why it needs to be an agent
18:47hiredmanso I can use send and send-off
18:48rhickeyso, right there, send-off can block, is that ok on the swing thread?
18:48hiredmanit unifies interacting with the event dispatch thread in an async way with clojure's other async construct
18:49hiredmanrhickey: send blocks on the thread sending the action doesn't it?
18:49rhickeyno
18:50rhickeysend and send-off always return immediately
18:50rhickeya blocking action will block the thread pool thread
18:50hiredmanoh, right
18:51hiredmanbut that is do different than invokeandwainting a looping Runnable
18:51hiredmanor looping inside an agent action
18:51rhickeyso send-off provides additional threads when needed, the event thread doesn't
18:51rhickeynot looping, blocking
18:52hiredmana looping action that doesn't complete would block
18:52rhickeyblock on IO in event thread - big no no
18:52hiredmanI am aware
18:53rhickeyso the semantics are simply not the same
18:53rhickeymaking it quite wrong to reuse the calls
18:53rhickeyhowever similar it may feel to you
18:53hiredman:(
18:53rhickeysorry
19:19cemerickit's interesting that the NetBeans project (which is GPL and CDDL) doesn't require contributor agreements of any kind.
19:20hiredmanhttp://www.netbeans.org/about/legal/ca.html <-- orly?
19:21cemerickhiredman: heh, OK, but they're taking my patches without my signing anything
19:22hiredmanmaybe the assumed you signed it?
19:22cemerickha
19:22cemerickwell, maybe.
19:22cemerickI don't care about my rights in this circumstance at all, but I hope they don't get in trouble for it.
19:24cemerickactually, the patches got put into hg without any attribution to me, so maybe that's good enough for government work as long as I don't complain about it
19:25fsmis there anywhere a todo list for contributing to clojure?
19:26fsmi would be happy to contribute even some grunt work, documentation tidying, that kind of thing
19:26technomancyfsm: there are tickets on assembla; not sure if they include tidying-up work
19:26technomancy~assembla
19:26cemerickfsm: http://clojure.org/contributing
19:26clojurebotassembla is http://www.assembla.com/spaces/clojure
19:27fsmwell, any mundane stuff really
19:27cemerickfsm: man, where were you when Chousuke and I manually moved the backlog to assembla?! ;-D
19:29fsmits a long time since i had enthusiasm about writing code, so i want to put back some effort
19:54somniumanyone who might be able to help with compojure/appengine? (or possibly just jetty + compojure servlet)