#clojure log - Sep 25 2009

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:03 drhodes: is there anything built in for doing something like (pow 3M (with-precision 20 (/ 1 3M)))

0:08 slashus2: no

2:09 tomoj: anyone know how to have slime setup for both clojure and, say, common lisp?

2:21 vy: tomoj: Just introduce related slime-lisp-implementation entries.

2:33 pixelman: I'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?

2:34 tomoj: pixelman: find-first in clojure.contrib.seq-utils does it

2:37 pixelman: tomoj: thanks!

2:40 ah, seq utils isn't in my version of clojure contrib

2:41 tomoj: you sure?

2:41 maybe it's old I guess

2:41 pixelman: ah no it was there

2:41 just misspelled clojure :)

2:41 tomoj: anyway this is the definition of find-first: (defn find-first [pred coll] (first (filter pred coll)))

2:41 vy: pixelman: 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.)

2:41 tomoj: so.. pretty simple

2:43 pixelman: didn't find it when I searched because it wasn't included.

2:44 ok by lazy that means not all of the list will be evaluated

2:44 ?

2:44 or that it will be evaluated only when function is called?

2:47 vy: AFAIK, `first' will force the evaluation of the very first element only.

2:49 pixelman: ok!

3:06 vy: pixelman: See clojure.contrib.seq-utils/find-first

3:06 http://github.com/richhickey/clojure-contrib/blob/master/src/clojure/contrib/seq_utils.clj#L170

3:07 pixelman: vy: thx! seems like it will not evaluate unnecessary stuff!

3:23 LauJensen: Good morning all

4:16 pixelman: ,(Math/round (+ 23/9 0.0))

4:16 clojurebot: 3

4:17 pixelman: is there a simpler way to round down a ratio to an integer?

4:19 crios__: guten tag!

4:20 jdz: ,(float 23/9)

4:20 clojurebot: 2.5555556

4:20 LauJensen: ,(int (+ 0.5 (/ 23 9)))

4:20 clojurebot: 3

4:24 LauJensen: ,(int (+ 0.5 23/9))

4:24 clojurebot: 3

4:25 LauJensen: pixelman: Thats the fastest simplest bestest way to go :)

4:25 pixelman: :)

4:26 ,(Math/round (float 23/9))

4:26 clojurebot: 3

4:27 LauJensen: pixelman: I don't think that's faster or better, do you ?

4:28 pixelman: LauJensen: :) I want it to work for any ratio

4:28 LauJensen: i5 2ill

4:29 oops

4:29 it will

4:29 ,(int (+ 0.5 3/4))

4:29 clojurebot: 1

4:29 LauJensen: ,(int (+ 0.5 1/4))

4:29 clojurebot: 0

4:29 pixelman: LauJensen: I missed your call to (int first

4:30 LauJensen: yeah, it'll work :)

4:30 LauJensen: it sure will baby :)

4:30 Somebody from in here taught me that 6 - 8 months ago, saying it was an old C trick

4:32 pixelman: C is full of stuff like that

4:33 are you from denmark?

4:33 LauJensen: Yep

4:33 pixelman: Then you'll probably appreciate the humor of this: http://unix.se/Gubb-C

4:34 eevar2: you want to round down? - I'd shoot for Math/floor and let the JVM inline as neccessary

4:34 LauJensen: haha :)

4:38 pixelman: there seems to be a round in clojure contrib that works with ratios

4:38 I'll use that I think

4:39 ,(round 2/3)

4:39 clojurebot: java.lang.Exception: Unable to resolve symbol: round in this context

4:40 pixelman: ,(clojure.contrib.math/round 2/3)

4:40 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.math

4:58 AWizzArd: LauJensen: You do json with compojure?

4:58 LauJensen: In one yes, case

4:59 AWizzArd: My 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.

4:59 How can I read a POST body in Compojure? (= the json form)

5:00 LauJensen: use contribs json reader (read-json (:body request))

5:04 AWizzArd: LauJensen: (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?

5:06 LauJensen: No 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

5:11 sfuentes: can someone explain what a lazy sequence means?

5:12 noidi_: sfuentes, it's a sequence whose values are generated only when needed

5:12 that way you can have an "infinite" sequence

5:13 ,(take 3 (repeat :foo))

5:13 clojurebot: (:foo :foo :foo)

5:13 noidi_: (repeat :foo) returns a lazy sequence full of :foo

5:13 ,(doc repeat)

5:13 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

5:14 noidi_: note that lazyness does not necessarily mean that the sequence is infinite

5:15 sfuentes: i see.

5:15 AWizzArd: LauJensen: unfortunately the json string really doesn't show up. I tried it this way: (http-agent "http://localhost:8080/echo" :method "POST" :body "{\"echo\" 123}" :headers {"content-type" "application/json"})

5:15 sfuentes: ,(repeat :foo)

5:15 clojurebot: Eval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space

5:15 LauJensen: AWizzArd: pmsg

5:16 sfuentes: ooops

5:16 did i break that?

5:16 Chousuke: clojurebot: ping

5:16 clojurebot: PONG!

5:16 noidi_: if you do that, the repl will try to print all of the sequence

5:16 which means that all of the (infinite) sequence has to be generated :)

5:16 sfuentes: i am so sorry.

5:17 Chousuke: sfuentes: don't worry, it doesn't affect clojurebot

5:17 sfuentes: i thought it would assume a sequence of 1

5:17 Chousuke: I suppose it'll just get the OOM exception and then the seq generated so far will get GC'd

5:19 noidi_: ,(+ 2 2)

5:19 ,(doc repeat)

5:19 clojurebot: 4

5:19 noidi_: hmm, did that really break clojurebot? :D

5:19 jdz: should not have

5:19 noidi_: maybe a bug in the sandbox?

5:19 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

5:19 Chousuke: laggy.

5:19 jdz: clojurebot had to catch up to the infinite sequence :)

5:20 you know, it takes time to GC an inifinite sequence

5:20 but clojurebot is fast

5:20 relatively

5:20 Chousuke: well, it gets GC'd lazily :)

5:21 the not-yet-generated items are GC'd only when needed :D

5:26 sfuentes: you guys are geeks

5:26 i like that

5:30 so what's the difference between using ";" versus "(comment)" ?

5:30 Chousuke: sfuentes: 'comment is actually a macro

5:30 so this can happen:

5:30 jdz: the stuff in comment must be valid clojure expressions

5:30 Chousuke: ,(comment #<error>)

5:30 clojurebot: Unreadable form

5:31 Chousuke: ,5 ;#<no error>

5:31 clojurebot: 5

5:32 sfuentes: so why would use ever use (comment ) ?

5:32 Chousuke: it's handy for commenting out entire expressions

5:32 clojurebot: for is a loop...in Java

5:32 jdz: especially if you have expression-aware editor, like emacs

5:33 Chousuke: or code that could be evaluated manually in a repl for example

5:34 sfuentes: ok, i see.

5:34 atome: the other diffence is (comment) evaluates to something

5:35 ,(nil? (comment blah))

5:35 clojurebot: true

5:35 Chousuke: the definition of comment is simply (defmacro comment [& body])

5:35 atome: which tripped me up a few times, eg if you use (comment ) at the end of a function it'll return nil

5:36 sfuentes: well i'm glad to see that folks in this channel are very helpful. thank you all.

5:37 LauJensen: np :)

5:37 (notice how I sneak in to steal the glory)

5:39 jdz: you can't steal it. stealing presumes ownership ;)

5:39 Fossi: ... glorypirate

5:41 LauJensen: jdz: Man it's hard to keep you happy :)(

5:42 jdz: nah, i just remembered a quote from "V for Vendetta"

5:43 i'm overall a very happy person :)

5:52 sfuentes: defn- means scoped to current file?

5:53 Chousuke: private to the namespace

5:54 sfuentes: ok

5:55 Chousuke: though it's pretty easy to override if someone really wants to. but don't worry about that :)

5:55 if someone goes and uses your private functions and things break, it's their fault :P

5:56 sfuentes: let them clean their mess :)

6:13 ambient: has anyone written games with clojure yet?

6:13 actual games, not something like minesweeper :p

6:15 jdz: your definition of "actual game" is very subjective

6:16 ambient: event loop, simulation-type engine, realtime

6:17 let's say asteroids done with opengl

6:17 jdz: look for "pong" in mailing list

6:17 that fits your description

6:18 not the best example of idiomatic clojure code, though

6:19 ambient: seems that it has been updated for more idiomatic clojure :)

6:19 http://jng.imagine27.com/articles/2009-09-12-122605_pong_in_clojure.html

6:19 thanks

6:30 RomanRoe: The clojure api doc says that watcher are experimental. Is this still up-to-date or can I consider them to be stable?

7:13 yason: How 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.

7:13 By creating the dang (defmethod ...) call as a list, instead of backquote?

7:19 LauJensen: ambient: I was working on one when I had the time for it, but you can finish it if you like

7:19 ~sofiaba

7:19 clojurebot: sofiaba is http://wiki.github.com/Lau-of-DK/sofiaba

7:29 Chousuke: ,`(foo ~'foo) ; tason

7:29 clojurebot: (sandbox/foo foo)

7:30 Chousuke: yason * :P

7:31 yason: Chousuke: much easier :)

7:32 Chousuke: I'm still not that familiar with that stuff (namespaces, fully-qualified symbols and just symbols)

7:33 pixelman: I 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

7:34 hm maybe I just can print it to a page, but it would be nice to get it on the log, or in the repl

7:35 Chousuke: yason: fully-qualified symbols are just symbols too. it's just that neither let nor fn allow them so you can't accidentally capture names.

7:37 yason: Chousuke: Yeah, I figured out a bit of that each time I used syntax quote for creating a template of something

7:38 Chousuke: capturing names is rarely needed though.

7:38 yason: Chousuke: 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 :)

7:38 Chousuke: most of the time it's better to just take the names you want to bind as parameters

7:41 yason: Chousuke: that would work but would cause lots of duplication on the user side :)

7:44 Chousuke: anyway, thanks for ~' -- it really makes sense now that I thought about it

7:50 crios__: Could I ask a bit challenging question?

7:50 What are the application domains for wich Clojure can hope to become a mainstream language, in your opinion?

7:50 LauJensen: For those interesting in rendering chaotic functions in 80 lines of code: http://www.dzone.com/links/chaos_theory_vs_clojure.html

7:50 interested :)

7:51 Fossi: crios: anything java is currently

7:51 crios__: Are you serious about that? :)

7:51 Fossi: sure

7:52 Chousuke: maybe not the super high performance stuff though. yet, anyway

7:52 Fossi: i wouldn't want to write a single line of java again if it were up to me

7:52 Chousuke: well, i have rarely seen super high performace java "stuff"

7:52 clojurebot:

7:55 pixelman: I've seen a lot of high-performance java stuff made in vain, designed to for loads exceeding 1000 times the actual use :)

7:57 a lot of java programs are designed performance first usability, maybe later...

7:58 I like not having to fall back on C for high performance stuff though

7:59 yason: pixelman: I can write a Python program that is designed for loads exceeding 1000 times the actual use. It just depends on the problem space :)

8:01 pixelman: yep. Most high performance stuff in python use C functions though, that's why it's fast.

8:02 there are some really good stuff in python for number crunching :)

8:02 ambient: numpy, mainly

8:03 Fossi: pixelman: same here

8:04 jdz: i'd prefer (iterate (partial * 2) 1) over (iterate #(* 2 %) 1) any time of day

8:04 Fossi: the most "high performance" code has been a smallish demo we wrote that reads some data from a memory-mapped file a

8:05 and processes them

8:05 but there is no reason that couldn't work with clojure i guess

8:05 although the immutable datastructures can get a little heavy for the gc (especially on dalvik)

8:06 pixelman: high performance stuff I dont like working with is when writing an app and everything with the db is a stored procedure.

8:07 but maybe it just sucks to work with from java

8:08 in lisp, maybe it's possible to write a really clean api

8:10 btw. is the a way to easily wrap a java access so that it'll just return nil for a null access? like (.getFoo myVoidObject)

8:10 instead of an exception?

8:11 Chousuke: (doc .?.)

8:11 clojurebot: "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 "

8:11 pixelman: Chousuke: thanks!

8:11 Chousuke: I think there's also -?>

8:12 pixelman: pretty cool

8:14 LauJensen: jdz: Are you dissing me again?

8:15 jdz: nope, i'm dissing #() sintax, if anything

8:16 LauJensen: It's cool :)

8:16 Chousuke: #() still has its uses though

8:17 pixelman: ,(.?.toString nil)

8:17 clojurebot: java.lang.NullPointerException

8:17 jdz: yes, but when everything else fails only

8:17 pixelman: how would I go about to use .?. ??

8:17 Chousuke: with comp and partial it's sometimes difficult to see what the actual operation is

8:17 not in this case though.

8:17 jdz: pixelman: (.?. nil .toString)?

8:18 Chousuke: sometimes. is (partial + 2) the case?

8:18 pixelman: jdz: thankx. am I stupid or what :)

8:19 Chousuke: jdz: I'm sure I can find you an example from clojurebot's source. a moment... :)

8:20 jdz: don't take me wrong. i do use #() in places, but as i said, only when everything else makes the code less readable.

8:20 it might be just me...

8:20 LauJensen: I agree jdz, and I'm glad I have you to point it out to me - I really am :)

8:20 Chouser: (->> (range 10) (filter odd?) (remove #(< 3 % 7)))

8:21 LauJensen: ~def ->>

8:21 clojurebot: No entiendo

8:22 LauJensen: Chouser, it's like -> but runs partial on all expressions?

8:22 cgrand: LauJensen: it's like -> but adds in last position instead of second

8:22 jdz: i think it's like ->, only adds the parameter to the end of argument list, not front

8:23 LauJensen: Thanks guys :)

8:23 * Chouser deletes his identical answer

8:23 jdz: never used it myself yet

8:24 Chouser: that example of yours is where the use of #() is justified and improves code comprehension

8:25 Chouser: jdz: because 'partial' wouldn't work?

8:29 jdz: Chouser: yes, it does not fit here

8:29 but then, putting arbitrary constants in code is bad

8:30 Chouser: all of that code was arbitrary. :-)

8:30 jdz: the remove expression could be replaced by something like (filter good-enough-for-me?)

8:30 giving names to things is good

8:30 Chouser: (def good-enough-for-me? #(< 3 % 7))

8:30 jdz: in the long term

8:30 Chouser: :-)

8:31 now I'm just antagonizing you.

8:31 jdz: (defn good-enough-for-me? [n] (< 3 n 7))

8:31 replace n by something meaningful for the problem domain

8:31 clojurebot: for is a loop...in Java

8:31 jdz: clojurebot: orly?

8:31 clojurebot: excusez-moi

8:32 Chousuke: that for factoid triggers way too often

8:33 jdz: in the end, code that is written and uses #() is a lot better than my unwritten code that does not use #() everywherne

8:33 umm, everywhere

8:35 Chousuke: heh

8:36 Chouser: "worse is better" in a nutshell

8:37 Chousuke: you could remove many of the #()s if java methods were automatically wrapped in functions when used as values

8:38 Chouser: Chousuke: yes, that most annoying ones at that.

8:38 Chousuke: but I don't know if doing that has any side-effects

8:39 Chouser: And 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 %)

8:39 (map #^{return-tag String} .toUpperCase ["one" "two"]) ; bleh :-(

8:40 (map #^{:return-tag String} .toUpperCase ["one" "two"]) ; even worse

8:41 jdz: (map (java-method .toUpperCase String String) ["one" "two"])...

8:41 Chouser: (map .toUpperCase #^[String] ["one" "two"]) ; hmmm...

8:41 ,(map #(.toUpperCase #^String %) ["one" "twp"])

8:41 clojurebot: ("ONE" "TWP")

8:42 Chousuke: hm

8:42 reminds me, I still have to fix my implementation of #() to preserve any metadata :/

8:43 Chouser: Chousuke: like for its return value?

8:43 er, wait, what?

8:43 Chousuke: in my reader.

8:44 I should also find the time to finish the thing but I've been a bit busy with studying lately

8:44 Chouser: yeah, but metadata on what? a fn?

8:44 Chousuke: the #^Foo tag on %

8:44 Chouser: oh, yeah, on %

8:44 Chousuke: as it is now my implementation simply replaces the % symbols with gensyms

8:44 Chouser: I don't the the reader does anything special with % anymore

8:44 ,'%

8:44 clojurebot: %

8:45 Chousuke: it does, within #() :/

8:45 ,'#(foo %)

8:45 clojurebot: (fn* [p1__3943] (foo p1__3943))

8:45 Chouser: oh

8:45 huh

8:45 I wonder why

8:45 LauJensen: Chouser: Did you see this? http://www.dzone.com/links/chaos_theory_vs_clojure.html That's my second post which turned jdz against #() :(

8:45 jdz: i'd like the following to work, too.

8:46 ,',

8:46 clojurebot: EOF while reading

8:46 Chousuke: jdz: why would you want to quote whitespace? :)

8:46 jdz: comma is not whitespace :/

8:46 Chousuke: yes it is.

8:46 in clojure :P

8:46 jdz: i want a symbol whose name is ","

8:46 Chousuke: (symbol ",")

8:46 jdz: but yeah, you have a point

8:47 Chousuke: but that's not very useful

8:48 Chouser: LauJensen: underscores!

8:49 jdz: LauJensen: if i'm not a domain expert, i don't have a slightest clue whether #(* (/ (- %1 %2) (- %3 %2)) %4) is correct or not

8:50 and you can't tell just by looking at it, too

8:50 rhickey: underscores - ick

8:50 jdz: at least you won't after 2 weeks

8:52 LauJensen: in your code, whenever i see #(), i see something that derserves a name. really.

8:52 Chouser: the use of #() in axis-seqs looks ok to me

8:53 rhickey: lots o swaps in there

8:54 jdz: Chouser: well, i might have swept some legit cases under the rug here. but i already mentioned the disclaimer ;)

8:54 Chouser: LauJensen: what it draws is pretty. Nice idea for a blog post!

8:58 rhickey: thanks for ->> Now hiredman can quit doing (-> ... partial ... partial ... partial) :-)

8:58 crios: come back. what happened to the web freenode chat

8:58 rhickey: hah

8:59 LauJensen: yes, nice idea

9:00 ,(doc ->>)

9:00 clojurebot: It's greek to me.

9:02 LauJensen: Chouser, rhickey, thanks guys

9:03 Chouser: LauJensen: You could use (while ...) instead of recur in animate

9:03 LauJensen: Chouser: What benefits would that give me ?

9:04 Chouser: it makes it more obvious that you've got an imperative loop doing mutation.

9:06 LauJensen: I guess that's true. Doesn't affect performance or anything like that ?

9:07 Chouser: ,(macroexpand-1 '(while foo (blah) (blah)))

9:07 clojurebot: (clojure.core/loop [] (clojure.core/when foo (blah) (blah) (recur)))

9:07 Chouser: nope, it's the same thing. :-)

9:08 LauJensen: Ah ok

9:09 I think I'll hang on to your idea for my "A tribute to Chris Houser" post :)

9:18 rhickey: your line 'lots o swaps in there', was a comment on my code, would you have modelled it differently? how/why

9:36 * LauJensen pouts

9:37 Chouser: LauJensen: 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?

9:38 LauJensen: yea

9:38 Put would it have been better to go with something other than atoms to get rid of the head?

9:39 Chouser: so it's likely there is a way to solve the head-holding problem without resorting to mutable state

9:39 LauJensen: hmm

9:41 Chouser: if 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"

9:42 then consume that seq using a normal non-head-holding thing (map, for, whatever)

9:44 basically just push those lazy seqs further down into your code instead of trailing off at 'spawns'

9:45 I understand you have swing at the other end trying to push side-effects and statefulness up, so there's definite tension there.

9:45 LauJensen: Ok, I'll try to model it that was for my 3D Lorenz attractor - I have a hard time visualising that last map though

9:46 Chouser: it's actually perfectly legitimate to draw on a swing canvas without waiting for a paint call

9:47 doing 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.

9:48 LauJensen: But that would spoil the animation effect wouldn't it ?

9:48 Chouser: how?

9:49 crios: Fossi, were you saying that clojure could *really* replace java in any domain application ?

9:49 LauJensen: I think I misunderstood you, can you explain ? :)

9:50 Chouser: LauJensen: http://gist.github.com/40012

9:51 there is code that "animates" drawing into a Frame without any mutable state. It doesn't even use proxy.

9:52 LauJensen: Oh I see

9:53 Chouser: It also doesn't do any of that hard math stuff. :-)

9:54 LauJensen: Would make for a good blog post Chris :)

9:54 Chouser: it was a good blog post, if I may say so myself. ;-)

9:54 LauJensen: ( and don't call that sorry presentation you did way back when a 'blogpost' )

9:55 Chouser: oh

9:55 yes, I seem to remember you complaining about it at the time.

9:55 LauJensen: hehe, I'm going back now to find it

9:55 oh yes now I see... it's awful

9:55 You really should delete that

9:56 crios_: 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

9:57 Chouser: crios_: cut off at "cost to migr"

9:57 crios_: where do you really believe that clojure have a chance to become a mainstream language?

9:58 Chouser, I think there is a cost to migrate a well oiled java team to a new language + frameworks

9:58 licoresse: What is the cost? When you're fed up with the verbosity of Java?

9:59 Chouser: crios_: 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:00 crios_: licoresse: Do you really think that a less verbose language has higher business value? how COBOL's life fit here?

10:00 Chouser: surely many people will never find Clojure attractive. It's sad but I believe it.

10:01 licoresse: crios_: No, not the way YOU put it, put I am sure you can see other ways

10:02 hopefully the pointy-hair-boss-generation is going to die out, haha

10:02 Chouser: I 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:02 licoresse: the ones that are scared to shit of new ideas

10:02 LauJensen: licoresse: They don't die, they become the bosses of the new bosses :)

10:03 licoresse: :)

10:03 Chouser: but without better tools to handle that concurrency, though, it's still a dangerous proposition. Clojure can help address that danger.

10:04 licoresse: well, what is another 25 years of stagnation

10:04 crios_: 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:05 Chouser: I 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:05 licoresse: of course not, but clojure is about *more* than verbosity, seriously...

10:06 what do I know, I am just getting excited, as I did when I first discovered Smalltalk

10:07 oh man, I was excited then, turtles all the way down... hehe

10:09 crios_: I'm too excited. But we work in very real teams and corporations :)

10:09 and I'd like to see where the clojure language could fit there

10:09 Chouser: I'm such a lisp weenie now. I look at code in some syntaxy language and it just hurts. :-(

10:10 licoresse: lisp weenie?

10:10 Chouser: was my definition there too vague?

10:11 LauJensen: crios, 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:11 crios_: I saw some web example written in clojure. It does not seem more readable than a scriplet jsp

10:11 licoresse: no, I was just surprised

10:11 crios_: "scripleted"

10:11 the code have to be readable

10:11 Chouser: licoresse: 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:12 crios_: see here: http://jng.imagine27.com/articles/2009-09-12-122605_pong_in_clojure.html

10:12 To be honest, this is just plain old spaghetti code! :)

10:12 Chouser: licoresse: and "aficionado" sounds pretentious and doesn't convey the slight negative connotation I was after.

10:12 crios_: see the actionPerformed function

10:13 licoresse: hmm

10:13 Chouser: crios_: yeah, that's not particularly idiomatic clojure. too much state

10:13 crios_: a java junior should migrate to clojure? never on my team! :D

10:13 licoresse: there are @ all over the place

10:14 crios_: you, for me, are power user, examples to follow if I want to become a clojure developer

10:14 licoresse: Chouser: personally, I don't mind aficionado

10:14 I am already using a mac, so per def. I am a zealot

10:14 (shit)

10:15 crios_: if your code is not so readable , how do I, a wannabe clojure student :), can have stimulus?

10:15 licoresse: I cannot see why it would be harder to learn a lisp, than to learn something algoish

10:16 Chouser: licoresse: 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:16 licoresse: Chouser: You've come to an end point. There is still something beyond, but you don't need it right now

10:17 I think that is perfectly ok

10:18 I need to go pick up the kids, later folks

10:18 crios_: bye

10:19 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:21 stuartsierra: Honest? No Lisp-derivative will ever go mainstream.

10:21 LauJensen: Ask the question "How could it not" ? Java isn't exactly 'up to date'

10:21 crios_: [I've no FUD intent, clearly. Just trying to understand you point of view]

10:21 [your]

10:22 Chouser: crios_: I'm mearly hopeful that Clojure could become sufficiently popular, not by any means convinced that it will.

10:23 crios_: I know (well) LauJensen. But COBOL, too, is decades which is "to be dying". But it was the best language for the business

10:23 thank you Chouser. So I'm not an alien :)

10:23 dnolen-rec: Chouser: 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:24 Chouser: where "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:24 crios_: +1 Chouser

10:25 Our field was (and is) full of buzz words, and "silver bullets" news

10:25 Chouser: dnolen-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:25 adityo: already making a *living* out of Clojure

10:25 Chouser: adityo: you are? congrats!

10:25 dnolen-rec: Chouser: 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:26 crios_: adityo: really?

10:26 Chouser: note that my definition there includes rhickey making a living using Clojure, since he wants to. We're not there yet. :-)

10:26 adityo: Chouser: convinced management to use Clojure instead of Common Lisp

10:27 yet to launch our products but development is on

10:27 crios_: adityo: in what application domains? What kind of software do you develope?

10:27 adityo: mainly web dev

10:28 crios_: entirely written in clojure?

10:28 Chouser: adityo: fantastic.

10:28 adityo: developing the backend for a news portal, using Clojure postgres and Java

10:29 crios_: your clojure code is written by ex-java developers or by ex-common lisp coders?

10:29 dnolen-rec: crios_: 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:29 adityo: i am a ex common lisper..

10:30 crios_: so adityo didn't you migrate java developers to clojure, do you?

10:31 adityo: actually no..but clojure has been a compelling case to prove to management to have Lisp like languages in an 'Enterprise' envirionment

10:32 rsynnott: I'm not sure that the primary goal of a language should necessarily be to be popular....

10:33 crios_: your management was already accustomed to that, being formerly accustomed to Common Lisp. Yet I see its value :)

10:34 rsynnott: of course not :) Just trying to be honest on its *real-business* applications

10:35 dnolen-rec: why was not clojure the right choice?

10:35 rsynnott: I think it has applications there

10:35 not necessarily terribly widespread applications

10:35 (if nothing else, the majority, possibly the vast majority, of all commercial programmers are idiots)

10:36 crios_: so the web2 / web-economy / web society is written by idiots? :D

10:37 rsynnott: "there"? where precisely? Again, I'm just trying to understand

10:38 rsynnott: I think it has applications commercially

10:38 dnolen-rec: crios_: 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:38 rsynnott: "so the web2 / web-economy / web society is written by idiots?" - broadly speaking, yes

10:38 the average quality of commercial code is STUNNINGLY low

10:39 dnolen-rec: no-one's gotten around to writing a parenscript equivalent, yet? :)

10:40 dnolen-rec: rsynnott: 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:40 * rsynnott was never really quite happy with parenscript, personally, but it's a nice idea

10:42 rsynnott: crios_: in particular, there is a lot of copy-and-paste coding out there; people writing stuff without actually understanding what they're doing

10:42 * dnolen-rec fantasizes about a Clojure -> JS compiler that can talk back to the server over comet to give accurate debugging information for Lisp :D

10:42 rsynnott: you don't need comet if you're only talking TO the server

10:43 if you're sending data to the CLIENT, then you need comet

10:43 dnolen-rec: rsynnott: for live debugging. Like Symbolic web.

10:43 rsynnott: ah :)

10:43 crios_: you're right rsynnott

10:43 Plus, add cost-cut operations

10:44 where junior developers replace senior

10:44 sproingie: hey 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:44 is there some common idiom in place to simulate call-next-method?

10:44 rsynnott: actually, 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:44 dnolen-rec: rsynnott: yup.

10:44 sproingle: have you looked at get-method?

10:44 * rsynnott has been using it for such experimentally

10:45 dnolen-rec: Google should be writing Wave in Clojure.

10:45 rsynnott: (replacing an older erlang-proxying-to-python comet system)

10:45 sproingie: dnolen-rec: i'm not sure how i'd use it

10:46 get-method appears to be single-dispatch

10:46 dnolen-rec: sproingle: if you dispatching on type you can look at the parent of the current type. and find the method for that type.

10:46 rsynnott: crios_: of course, many senior developers are also incompetent :)

10:47 sproingie: sure, but i'm not always certain which parameter the next method dispatches on

10:47 crios_: anyone here? ;-)

10:47 rsynnott: (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:47 Fossi: word

10:48 sproingie: i 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:48 crios_: by the way, about the "cloud" buzzing: http://java.sun.com/javaone/2009/articles/rockstar_click.jsp

10:49 tmountain: ~logs

10:49 clojurebot: logs is http://clojure-log.n01se.net/

10:49 crios_: "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:49 I think so, too

10:49 dnolen-rec: sproingle: hmmm, if you want CLOS like behavior I think mikel did some work on a library called generic functions

10:50 sproingle: http://code.google.com/p/explorersguild/wiki/XGModelAndGF

10:50 rsynnott: to a large extent, the cloud thing is just marketing

10:50 sproingie: dnolen-rec: ooh looks exactly like what i'm looking for, thanks :)

10:51 dnolen-rec: np

10:52 crios_: 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:53 Today, programming as "code snipplets combination" seems to be the future! I don't like that, too

10:54 rsynnott: very dangerous, though; it allows people to write software which SEEMS to work, without understanding what they're doing

10:54 crios_: more people, lesser quality

10:55 rsynnott: I suspect the Great Recession is driving up the quality if programmers to an extent by reducing the size of the job market

10:55 crios_: so, your question was: can this "idiots" people really understand clojure?

10:55 rsynnott: I suspect that they might have more trouble with it than, say, php or java

10:55 which is no bad thing :)

10:56 crios_: ;)

10:59 adityo: is it yours? :O http://ericlavigne.wordpress.com/2008/12/28/using-postgresql-with-compojure/

11:00 Chouser: shouldn't functional code be *more* amenable to copy&paste than procedural code?

11:02 rsynnott: in general, people who do copy-and-paste programmng will not learn new things :)

11:02 crios_: Chouser: good question. Maybe yes . Expecially if uses pure functions

11:02 rsynnott: if clojure were ever to become very big in industry, the same problem would no doubt emerge

11:02 (as any technology gets more mainstream the average user usually gets stupider)

11:03 though for whatever reason some are a little resistant; python for instance seems to be extremely offputting to the copy-and-paste crowd

11:04 crios_: in general, it depends on how the useful code is refactored into imported libraries

11:04 I mean, fewer code to copy, if it is into a library

11:12 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:13 Chouser: crios_: will servers not have multiple cores?

11:14 tmountain: crios_: I think it matters anywhere that there's more than one core

11:14 crios_: well, multiprocessor servers are a news?

11:15 tmountain: crios_: 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:17 crios_: just for fun, an example of an old multiprocessor: http://3.bp.blogspot.com/__QeUMay1P8w/Se2Jtk7R0rI/AAAAAAAABX8/GIRtzZjzLIQ/s1600-h/multiprocessor.jpg

11:17 tmountain: could you explain better the "fanfare" part?

11:21 tmountain: google'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:21 of course, you could just use one of the existing frameworks out there to do the job for you

11:22 hamza`: 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:22 tmountain: but a lot of projects demand a higher level of customization

11:23 crios_: tmountain: I understand. So the hype on server side is into the "distributed" processing, maybe?

11:25 tmountain: tmountain: 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:25 oops, refere'd to myself there :p

11:26 hamza`: have a look at clojure.contrib.server-socket

11:26 hamza`: probably a good starting point

11:26 crios_: all that kind of stuff lends itself to parallel processing in a big way

11:27 crios_: tmountain: mmm still I believe they'll stay just "business niche"

11:27 at least, in short time terms

11:27 hamza`: 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:28 i am going to be reading from a packet capture lib when i have enough packets i want to exit.

11:28 loop and process them.

11:30 tmountain: hamza`: http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#Looping_and_Iterating

11:30 hamza`: a loop / when / recur construct would probably do what you want

11:34 crios_: I have to go. Thank you all for the very interesting discussion.

11:34 ciao

11:46 Chouser: hamza`: (take n (repeatedly #(read-from-socket))) may work, depending on your performance requirements

11:53 mtm: ,(int (+ 23/9 1/2))

11:53 clojurebot: 3

12:01 arohner: having hashmaps and the HOF map share the same name is getting annoying

12:02 I want to run map on the keys of a map, and I keep saying map

12:02 Chouser: arohner: yes, it's unfortunate

12:03 You can say hash-map and be inaccurate, or IPersistentMap and be wordy, or clojure.core/map and be wordy the other way ... :-/

12:03 mccraig: is there a clojure api for globbing filenames from a directory ?

12:04 Chouser: mccraig: file-seq might be close to what you want

12:05 or (filter #(re-find #"\.txt" (.getName %)) (-> "/tmp" java.io.File. .listFiles))

12:08 ordnungswidrig: Chouser: #"\.txt$" you mean?

12:08 Chouser: ordnungswidrig: sure

12:08 ordnungswidrig: Didn't mean to nitpick.

12:08 Chouser: :-) np

12:09 if we're not willing to nitpick, we're in the wrong field.

12:09 ordnungswidrig: yeah, fp nitpicking

12:09 bettern than oo design

12:10 I wondered why I have such strange 404 requests in my clojure console. But only when working at home.

12:11 Actually it was my android phone which tried to reach a funambol server at localhost:8080 only when my wlan.

12:11 *doh*

12:13 mccraig: Chouser: that should do fine. thx

12:13 ordnungswidrig: emacs users here?

12:13 (and awake?)

12:13 manic12: yeah

12:13 sorta awake

12:16 ordnungswidrig: manic12: 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:17 manic12: whatever mode I'm using, after you type the closing paren it highlights the opening one

12:20 ordnungswidrig: hmm. thanks.

12:20 manic12: sorry i couldn't have been more help

12:25 ordnungswidrig: manic12: another one. How can I disable the current line highlighting. I don't remember the option / face / variable

12:26 manic12: i dunno that one, because mine does not do it by default

12:27 stuartsierra: ordnungswidrig: turn off hl-line-mode

12:27 ordnungswidrig: stuartsierra: thax.

12:31 mtm: global-hl-line-mode will toggle it for all buffers

12:31 LauJensen: Is there a simple way to get something like "2009-09-11" by subtracting 14 days from today, without involving Joda ?

12:35 stuartsierra: Weeeel, (.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:39 or use java.util.Calendar, which is even more complicated

12:40 manic12: get-univeral-time...d'oh

13:49 abedra: are there any geolocation libraries available for clojure yet?

13:51 * dysinger greets

13:52 dysinger: Hey 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:52 the asm version is 3.1

13:52 what's the version of clojure ?

13:52 ddonnell: abedra: can you be more specific?

13:52 dysinger: it's just inlined into the clojure repo right ?

13:52 abedra: ddonnell: i'm looking to turn addresses into geocodes to draw points on a google map

13:54 ddonnell: abedra: is there a particular service you want to use for the geocoding?

13:55 abedra: ddonnell: not in particular, I was just wondering if anyone had started down this path

13:55 ddonnell: if not, I will just figure it out

13:57 ddonnell: abedra: i don't know of any clojure specific ones, but it's pretty easy to use the api's from places like google

13:58 emacsen: Is there a generic function to take a string and return it as a number?

13:58 there must be, since the repl does it...

14:00 Chouser: ,(read-string "45M")

14:00 clojurebot: 45M

14:01 emacsen: heh- good call :)

14:01 Chouser: might need *read-eval* false

14:07 emacsen: Chouser: 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:09 andysp: abedra: the Fmaps HTTP geocoder is quite simple

14:09 doesn't really nead a wrapper lib

14:09 *GMaps that is

14:09 emacsen: andysp: geocoder?

14:09 Chouser: emacsen: you've got a couple options

14:09 emacsen: andysp: use geocommons :)

14:10 Chouser: emacsen: (defmulti my-str ...) (binding [str my-str] ...)

14:11 emacsen: Chouser: right, so that's essentially my own version of str

14:11 no?

14:12 Chouser: (proxy [Object] (toString [] ...))

14:12 or manipulate your namespace 'refers' so that 'str' is your own rather than clojure.core/str

14:13 that's all I can think of.

14:13 emacsen: Fair nuff

14:13 thx

14:13 Chouser: oh, print-method is a multimethod, so if that's why you want to tweak it, you can do it at that level

14:13 emacsen: Chouser: basically I want to be able to print my struct (which I know is just a map) in a specific way

14:14 that's the reason for all this

14:14 andysp_: did you get my previous suggestion?

14:15 Chouser: emacsen: ah, then print-method will be perfect

14:15 emacsen: cool thanks!

14:17 Chouser: (defmethod print-method :my-thing [o w] (.write w (str "#<this is my thing>")))

14:17 #^{:type :my-thing} ['whatever] ; prints: #<this is my thing>

14:18 emacsen: thx

14:18 Chouser: np

14:25 hamza`: 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:27 Chouser: ,(vec (map #(str "12." %) (range 1 12)))

14:27 clojurebot: ["12.1" "12.2" "12.3" "12.4" "12.5" "12.6" "12.7" "12.8" "12.9" "12.10" "12.11"]

14:28 hamza`: lol thx, much shorter than what i was thinking.

14:28 (map str (partition 2 (apply vector (interleave (repeat "12.") (range 1 255)))))

14:29 Chouser: right. replace str with (partial apply str)

14:30 or #(apply str %)

14:30 and use vec instead of apply vector

14:30 hamza`: kk thx, yours is much more readable

14:30 Chouser: yours might be required depending on specifics. :-)

14:32 licoresse: ,apply

14:32 clojurebot: #<core$apply__3948 clojure.core$apply__3948@11b8a6b>

14:32 licoresse: ,(doc apply)

14:32 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

14:32 hamza`: for each item in this list i need to call a function with side effects is it ok to use apply or map?

14:33 Chouser: apply won't do it. map is not for side-effects. try doseq

14:33 hamza`: ok

14:34 Chouser: if you need both the side effects and the return value -- you're probably doing something wrong. :-)

14:34 but if you still need both, you could use (doall (map ...))

14:34 hamza`: no, no need for return just write to disk for each and i am done

14:34 licoresse: so doall can be recognized as a smell

14:34 ?

14:35 ,(doc doall)

14:35 clojurebot: "([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:36 hamza`: ,(doc vec)

14:36 clojurebot: "([coll]); Creates a new vector containing the contents of coll."

14:37 licoresse: ah, this head-retaining-thing...

14:41 Chouser: well, 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:41 licoresse: I like the analogy

14:42 Chouser: and I suppose lazy seqs with side effects aren't inherently wrong, just a little fragile.

14:47 hamza`: 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:48 Chouser: your design is fine except for the io in dosync

14:48 technomancy: hamza`: if you set it off in an agent, it will only write if the transaction succeeds

14:48 but it will *not* get you a guaranteed atomic commit-and-write like a real RDBMS

14:49 Chouser: or you could put a watcher on the ref

14:49 technomancy: even better

14:50 hamza`: 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:51 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:52 Chouser: hamza`: look at add-watch

14:52 I don't understand your second question. You can look at the contents of a single ref from anywhere at any time

14:54 hamza`: 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:54 i mean which one is more idiomatic?

14:56 Chouser: probably do it all inside a dosync. I think dosync is quite cheap until you start setting things.

14:56 don't use ref-set to update it though, use alter

14:57 hamza`: performence reasons or something else?

14:57 ,(doc alter)

14:57 clojurebot: "([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:57 Chouser: something else. :-) using alter allows you to apply a pure function to state, transitioning it from previous to next state.

14:57 the future is a function of the past [or at least should be]

14:58 ref-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:59 hamza`: ok, now i get it.

15:16 gcv: I could use a little help with macro scope rules:

15:16 (let [f1 #(inc %)] (defmacro m1 [x] `(~f1 ~x)))

15:16 Then: (m1 12) throws an extremely unhelpful exception.

15:17 This idiom works perfectly in Common Lisp.

15:18 Chouser: I assume that's a simplification?

15:18 gcv: yes :) but the general idea is to lexically capture a function inside a macroexpansion.

15:19 Chouser: it 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:19 ...trying to remember...

15:20 sgtarr: run into what?

15:20 Chouser: this type of question

15:21 sgtarr: oh

15:21 Chouser: yes, ok, it has to do with functions not being printable readably.

15:23 stuartsierra: I would write (defmacro m1 [x] `(let [f# (fn [y#] (inc y#))] (f# ~x)))

15:23 Chouser: or put the fn in var instead of in a local

15:24 gcv: alas, this is where simplification bites --- this is for a macro defining macro, where the outer accepts an arbitrary function parameter

15:25 Chouser: can you not just insert the form of that function?

15:26 oh, I see -- it may itself be a local referring to an anonymous fn rather than the anonymous fn form itself?

15:27 gcv: live code: http://paste.lisp.org/display/87728

15:27 it's broken in a subtle way right now

15:29 if 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:29 Chouser: the auto-gen-sym won't work across multiple `

15:29 gcv: interesting, so that's clearly another problem

15:30 actually, the code does work, as long as all symbols are visible

15:30 Chouser: really! hm.

15:31 ,`(foo var# `var#)

15:31 clojurebot: (sandbox/foo var__4024__auto__ (quote sandbox/var__4023__auto__))

15:31 Chouser: ah, neat!

15:31 `(foo var# `~var#)

15:31 ,`(foo var# `~var#)

15:31 clojurebot: (sandbox/foo var__4028__auto__ var__4028__auto__)

15:32 Chouser: you're right! My experience with macro-writing-macros is clearly quite shallow...

15:33 gcv: anyhow, 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:33 stuartsierra: Don'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:34 gcv: stuartsierra: it's worth a shot, but I think my problem is in scoping rules

15:34 licoresse: interesting..

15:34 Chouser: gcv: you might try using ~`~open-fn instead of ~'~open-fn

15:35 no, scratch that.

15:36 gcv: the 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:37 besides, 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:37 ^is a closure^closes over something

15:38 Chouser: I'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:38 stuartsierra: But in CL #'(lambda ...) is considered a literal.

15:39 Chouser: another 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:40 but 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:40 I think there are plans to change that

15:40 technomancy: ` doesn't expand to quasiquote?

15:41 Chouser: technomancy: it's called syntax-quote in clojure, and no I don't think so.

15:41 ,''5

15:41 clojurebot: (quote 5)

15:41 Chouser: ,'`5

15:41 clojurebot: 5

15:41 * technomancy learns a new thing

15:41 gcv: sorry, that went over my head. quasiquote?

15:42 lpetit: hi all

15:42 Chouser: one could imagine a ` that at read-time expands to (syntax-quote ...) just like ' reads as (quote ...)

15:43 but that's not what happens now

15:45 gcv: very interesting

15:48 thanks 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:48 Chouser: gcv: a very intersting problem, thanks for sharing.

15:49 gcv: it may be worth posting to the google group -- wider audience and more available time for thought

15:49 stuartsierra: I think you can't refer to an anonymous function in a macroexpansion.

15:49 Because it doesn't have a literal representation.

15:49 You can only refer to a locally-bound symbol.

15:49 Chouser: it 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:06 lisppaste8: Chouser pasted "macro-defining macros across namespaces" at http://paste.lisp.org/display/87734

16:08 Chouser: gcv: 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:09 gcv: Chouser: that does help. thanks! but you're also right about the fn form making things worse. :(

16:09 Chouser: so rather than a simple-minded (symbol ...) call, I think you'd have to walk the form qualifying every symbol you find

16:09 gcv: I'm composing a message to the Google group

16:10 Chouser: ...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:10 all of which is separate from your original question, btw. :-)

16:10 gcv: this particular use isn't worth the effort, either. I don't like the boilerplate with-db* macros I'll end up with

16:11 Chouser: I mean, your original simplified form demonstrated a different issue.

16:11 gcv: well, it's a discussion of solving the problem which bit me in the first place

16:11 that was just an attempted workaround

16:11 Chouser: ok, sure.

16:11 gcv: actually, looking at this message I'm writing, I'm not sure which of the two to attack

16:11 Chouser: fwiw, the idea of makeing with-open more general has come up before. I think there's a non-macro solution in the works.

16:12 hiredman: :|

16:12 we just need scopes!

16:12 ~scopes

16:12 clojurebot: No entiendo

16:12 hiredman: ~scope

16:12 clojurebot: scope is at http://paste.lisp.org/display/73838

16:12 gcv: hiredman: scopes! if only you knew how badly this code I'm writing could use those

16:12 Chouser: hm. indeed.

16:13 hiredman: gcv: I have an implementation that worked (last time I used it, months ago)

16:13 gcv: hiredman: link?

16:13 hiredman: just a second

16:14 gcv: fwiw, I hacked around needing scopes for the time being, but I welcome the opportunity to make my code more useable

16:14 hiredman: http://github.com/hiredman/clojurebot/blob/90fd15bec80bacd7c41cca41c971279587aa25ae/hiredman/horizon.clj

16:14 called it horizon instead of scope

16:15 the only real testing I did was to make sure rhickey's scope example worked

16:17 gcv: kinda cool

16:18 hiredman: it's nice for resouce management

16:18 gcv: I'm guessing the official implementation wouldn't use dynamic variables for state

16:18 hiredman: I have no idea

16:18 gcv: Resource 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:19 hiredman: you can definitely get into trouble when combining dynamic+lazy

16:21 but 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:23 dhaza: is the clojure wikibooks.org page a good repo for all the clojure PDFs/ebooks out there?

16:23 freely licensed ones, that is

16:26 hiredman: I don't know that there are any

16:30 crios: a maybe stupid question, out of curiosity: in Lisp is there an automatic memory management?

16:30 mDuff: crios, yes

16:30 gcv: crios: Lisp is the first language to ever have had a garbage collector. It was written sometime before 1959.

16:31 crios: yes. I'm reading "Coders at work", and I was assuring to have well understood

16:31 hiredman: crios: gc has been called part of the dna of lisp

16:32 crios: After having worked in Lisp and C, when turned to Java it felt a "return to Lisp"

16:33 it says: "memory management. that functions felt more like functions that subroutines"

16:33 [he says]

16:33 gcv: I haven't read the book yet. Is this the Guy Steele interview?

16:34 sproingie: when functions aren't even first-class objects, i can't see how it's in any form like a return to lisp

16:34 crios: peter seibel: http://www.amazon.com/Coders-at-Work-Peter-Seibel/dp/1430219483

16:34 sproingie: seeing gc as the defining characteristic of lisp is about as warped as it gets

16:35 gcv: sproingie: it's a common view among a certain generation of hackers.

16:35 I had a professor in college who called Java "a weak reimplementation of the semantics of Lisp."

16:35 sproingie: among those whos first exposure to gc was from lisp

16:35 and to some it would appear, their only

16:35 gcv: basically yeah

16:35 hiredman: *cough*

16:36 crios: sproingie: "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:36 sproingie: huh

16:36 i've done C for more than a decade, never felt "tempted" to use a goto

16:36 crios: java enforce more than C to write a structured code

16:37 hiredman: if 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:37 crios: :) just reporting the thought of Emacs / Netscape hacker

16:37 dhaza: gotos can make sense if you want to ensure a block of code executes after a complex code chain in a function

16:37 sproingie: hiredman: subtitle: phil greenspun falls into the turing tarpit

16:38 * mDuff has a sudden urge to read some Hofstader

16:38 sproingie: forward-only gotos aren't so bad in C. mostly because C doesn't have a 'break LABEL' syntax

16:39 dhaza: right. ive very rarely seen goto abused in actual code

16:39 ie not demonstration code of why goto is bad

16:39 sproingie: i've seen it to redo a loop body which i tend to think is abuse

16:40 crios: in java, you can "goto" just to exit loops. But also breaks and continue should be avoided

16:40 sproingie: but it was in seriously performance-critical code

16:40 so i'd probably have done the same

16:40 gcv: goto is pretty essential in C for cleaning up resources

16:40 crios: ok ok, no flame "goto" war now - the times are gone :)

16:40 sproingie: rule of thumb is you should at least be able to keep the goto and the target label on the same screen

16:41 crios: interesting

16:41 in order to enhance its readability

16:41 ordnungswidrig: sproingie: that rule might work on a 12in terminal, not with today 30in screens

16:41 sproingie: goto is a crude tool, real hackers use Duff's Device

16:41 ordnungswidrig: sproingie: and schwartzian transform

16:41 crios: what?

16:42 sproingie: schwartzian transform is decorate-sort-undecorate and comes from lisp

16:42 in fact schwartz pointed that out

16:42 ordnungswidrig: crios: duff's device is a manual loop unrolling using modulo operator and a case switch

16:42 sproingie: i like how python does it, you pass a 'key' function to sort()

16:42 ordnungswidrig: sproingie: schwartz is the first thing you lern doing perl

16:43 does pyhton sort do the schwartz?

16:43 sproingie: it's built in

16:43 sort(mylist, key=somefunc)

16:43 (sorted() actually but who's counting)

16:44 * ordnungswidrig doesn't want to imagine what my fellow java developers would do instead of a schwartz. certainly a lot of copy-the-collection-and-sort-in-place-horrible-stuff :-)

16:44 sproingie: i do just use the schwartz actually. and yes it looks awful.

16:45 you can use a custom comparator, but it's horribly inefficient

16:45 you have to use one anyway for schwartz but at least it's a generic one

16:46 dealing with collections is why i'd rather use clojure than go back to straight java :)

16:47 crios: ordnungswidrig: maybe could use a Collections.sort and a custom Comperator

16:47 cemerick: ah, so many new faces :-)

16:47 crios: or Comparable

16:47 who remember :D

16:48 ordnungswidrig: crios: the point with schwartz is not to transform the key for every single transform.

16:49 crios: is the goal having an object list sorted?

16:49 dhaza: crios, yes, but specifically when the comparison takes a long time to compute

16:50 ordnungswidrig: crios: so schwartz is about caching the result of the key-extraction.

16:50 dhaza: its a much fancier name than what it actually does

16:50 crios: mmm "The Schwartzian Transform is notable in that it does not use named temporary arrays."

16:51 http://en.wikipedia.org/wiki/Schwartzian_transform

16:52 ordnungswidrig: dhaza: I think it's fameous because it's idiomatic perl. Don't sort without the schwartz :-)

16:53 crios: "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:53 interesting

16:54 so clojure should support it?

16:54 dhaza: why wouldnt it?

16:54 its just a technique, it has little to do with the language

16:54 crios: yes, just noting the "memoization" outline

16:56 dhaza: yes, it should be pretty easy to make idiomatic clojure to handle it :)

16:57 are there any stats on how many people are using clojure in a production env?

17:00 hiredman: http://www.indeed.com/jobtrends?q=+jruby%2C+groovy%2C+scala%2C+clojure groovy? seriously?

17:00 dhaza: some kind of joke no doubt

17:01 who knows more..indeed.com or google? http://www.google.com/trends?q=jruby%2C+groovy%2C+scala%2C+clojure&ctab=0&geo=all&date=all&sort=0

17:01 crios: well, maybe grails

17:01 cemerick: dhaza: nope, there's lots of groovy programmers out there

17:01 there's a pile of them building apps on the netbeans platform, as well.

17:01 crios: the grails framework uses groovy

17:01 dhaza: wow 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:03 crios: it seems Scala is the JVM winner :D

17:03 oops wrong channel :P

17:03 cemerick: hopefully there won't be one winner again

17:04 hiredman: well, groovy is also a real word

17:04 crios: what do you mean cemerick?

17:05 cemerick: crios: I want a polyglot programming world, with common platforms (jvm and clr)

17:05 hiredman: I really cannot see scala "winning"

17:05 crios: hiredman: also scala is a real word (in Italian)

17:05 cemerick: Someone on the artima thread suggested scala : java :: C++ : C, which is a pretty decent way to look at it

17:06 IMO, of course

17:06 ordnungswidrig: http://www.indeed.com/trendgraph/jobgraph.png?q=+jruby%2C+scala%2C+clojure%2C+haskell%2C+common+lisp

17:06 hiredman: and see whatever one thinks of C++

17:06 ordnungswidrig: haskell plays a notable as well

17:06 s/notable/\0 part/

17:07 crios: well, a great part!

17:07 hiredman: first time I've ever seen someone use a backreference in an irc regex correction

17:07 dhaza: so scala is a hacked together POS that worried more about backwards compatibility with a different language than sanity?

17:08 hiredman: that is harsh

17:08 dhaza: i dont really think C++ is a POS

17:08 i quite like it

17:08 but why they made design decisions based on C is beyond my comprehension

17:08 maybe it made sense in 1992

17:08 hiredman: I think scala is too tied to OOP

17:10 crios: well , someone says: I'm aquainted with oop, when if I need can use a more functional approach

17:10 Scala enables this shift

17:10 "soft shift"

17:10 ordnungswidrig: hiredman: I'd expect any serious irc-bot to apply to regex automatically :-)

17:11 POS? What's a POS?

17:11 dhaza: piece of shit

17:11 i didnt mean it literally

17:11 ordnungswidrig: dhaza: :-) But hacked together get's it to the point.

17:12 dhaza: i speak only like that as someone who had to program in half-broken C++ for a couple years

17:12 symbian OS C++...does not support try/catch, but supports TRAP(), which is heavier weight and dumber than exceptions

17:12 hiredman: for 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:12 dhaza: of 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:13 fsm: Hi, I seek comments on my clojure code, any improvements in style or to make it more idiomatic, if anyone would like to look

17:13 ordnungswidrig: Can't clojurebot do this yet?

17:14 hiredman: clojurebot: whose job is it to ensure iodmatic coding?

17:14 clojurebot: that's j0ni's job

17:14 ordnungswidrig: In #haskell the bot would convert your code to point-free-style ;-)

17:14 I doubt point-free would give idiomatic clojure

17:14 fsm: well, my first try in a lisp/functional language

17:14 it's hard to know what is good or bad

17:15 hiredman: ordnungswidrig: clojure's functions don't have a way of querying arity information

17:15 makes that kind of thing harder

17:15 well, maybe not

17:16 ordnungswidrig: point-free lisp would make you go nuts because of the number of parents wouldn't it?

17:16 hiredman: first a transform into -> style, from which point free can fall out pretty easily

17:16 fsm: if there are any takers, please look to http://code.google.com/p/cray/source/browse/

17:16 any comments are welcome

17:17 hiredman: http://gist.github.com/184831

17:18 ordnungswidrig: hiredman: that cries for a macro to get rid of all those "partial" forms :-)

17:18 hiredman: but otherwise ice

17:18 fsm: also, anyone doing project euler?

17:18 hiredman: ~euler

17:18 clojurebot: euler is http://clojure-euler.wikispaces.com/

17:18 fsm: i have completed 28 questions so far

17:19 ordnungswidrig: hiredman: is it production code or a example you hackes together?

17:19 hiredman: that's part of clojurebot

17:19 ordnungswidrig: hiredman: you're the one behind clojurebot, right?

17:19 hiredman: ~ticket search Serializable

17:19 clojurebot: ("#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:19 hiredman: yes

17:19 ordnungswidrig: ~mapcat

17:19 clojurebot: No entiendo

17:19 hiredman: ,(doc mapcat)

17:19 clojurebot: "([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:19 hiredman: ~def mapcat

17:20 ordnungswidrig: too fast for me

17:21 crios: what is the "project euler" ?

17:21 ordnungswidrig: how would I model a datatype like "Either" in clojure? A list?

17:21 fsm: http://projecteuler.net

17:21 programming/math puzzles

17:21 a fun challenge if you can resist looking up the answers

17:22 hiredman: ,(:A {:A 1 :B 2})

17:22 clojurebot: 1

17:22 hiredman: ,(:B {:A 1 :B 2})

17:22 clojurebot: 2

17:22 crios: fsm: oh I see, thank you.

17:22 ordnungswidrig: hiredman: or like that.

17:22 fsm: beware, it is addictive

17:24 crios: fsm: I was noting it!

17:25 ordnungswidrig: hiredman: 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:25 hiredman: ,(doc -?>)

17:25 clojurebot: "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:26 kanak: Hi. I'm new to clojure, and I'm not sure how to use a function I've defined in another clj file.

17:26 ordnungswidrig: ~def -?>

17:27 crios: what?

17:27 ,(-?> \"foo\" .toUpperCase (.substring 1))

17:27 clojurebot: Unsupported character: \"foo

17:27 crios: ,(-?> "foo" .toUpperCase (.substring 1))

17:27 clojurebot: java.lang.Exception: Unable to resolve symbol: -?> in this context

17:27 * ordnungswidrig should take a look at contrib

17:27 hiredman: kanak: depends on this that and the other, but you can just use load-file

17:27 ordnungswidrig: How can I get the cwd of the clojure process?

17:28 hiredman: ugh, clojurebot is out of sync

17:28 crios: ,(clojure.contrib.core/-?> "foo" .toUpperCase (.substring 1))

17:28 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.core

17:29 kanak: hiredman: is that different from, say using "use" or "require"?

17:29 hiredman: yes

17:30 ,(use 'clojure.contrib.core/-?> "foo" .toUpperCase (.substring 1)) 14:33 clojurebot : java.lang.ClassNo

17:30 clojurebot: java.lang.Exception: Unable to resolve symbol: .toUpperCase in this context

17:31 hiredman: ,(use 'clojure.contrib.core)

17:31 clojurebot: nil

17:31 hiredman: ,(-?> "foo" .toUpperCase)

17:31 clojurebot: "FOO"

17:31 hiredman: ,(-?> nil .toUpperCase)

17:31 clojurebot: nil

17:31 hiredman: ~def -?>

17:32 gar

17:33 crios: time to go

17:33 hiredman: ah

17:33 crios: 'night

17:33 hiredman: no that is right

17:33 kanak: hiredman: 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:34 hiredman: kanak: depends, does each file declare it's own namespace?

17:35 kanak: hiredman: not yet. i'm not sure how to use namespaces either. :(

17:36 hiredman: ok, then load-file is fine

17:36 kanak: hiredman: but after i use ns to create the namespace, I can start using "use"?

17:36 ordnungswidrig: How to I tell the swank repl in which directory to launch clojure?

17:36 hiredman: ~namespace

17:36 clojurebot: namespaces 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:37 kanak: thank you for your help.

17:37 hiredman: kanak: as long as you have the correct classpath, the correct namespaces, and the correct directory structure

17:37 correct meaning they all reflect the information in the other two

17:38 kanak: thanks. do you know of any newbie friendly guide to classpaths?

17:38 hiredman: classpaths are pretty simple

17:39 kanak: so if i want a package a.b.c, my directory structure has to be a/b/c ? is that correct?

17:39 hiredman: it's a list of directories or jars to search inside for classes

17:39 yes

17:39 and the directory a is in has to be on the classpath

17:40 kanak: where/how do i set the classpath?

17:40 hiredman: via the -cp switch to java

17:40 kanak: gotcha. thank you so much. let me see if i can get this to work. :)

17:40 hiredman: the -cp switch and the -jar switch are mutually exclusive, fyi

17:49 fsm: random question - would mapcat be worse than reduce concat for large collections?

17:50 ordnungswidrig: quick! Are http header names case sensitive?

17:52 technomancy: ordnungswidrig: no

17:53 arbscht: but many implementations care, so in practice, often yes

17:53 ordnungswidrig: so compojure gives me a map of headers. how do I extract one case-insentively?

17:54 hiredman: rhickey: how would you feel about a patch that adds a layer of indirection between Agent and Agent.Action

17:55 (headers :header (headers :HEADER))

17:56 rhickey: I'd like to make it possible to use the agent interface ontop of other executor like things

17:56 (like swingutils/invokeandwait)

17:56 ordnungswidrig: hiredman: that looks really ugly

17:57 mtm: hiredman: that reminds me of 'buffalo buffalo...' http://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo

17:58 hiredman: ordnungswidrig: I'd really hope compojure or the servlet stuff it's built on would convert everything to some consistent case

17:58 ordnungswidrig: mtm: *buffulo*

17:58 mtm: arg. I meant "buffalo *g*"

17:58 sproingie: badgher badger badger badger badgher badger badger badger badgher badger badger badger MUSHROOM MUSHROOM

17:58 mtm: :)

17:58 hiredman: if not, it might be possible to create a ring middle ware layer that does it

17:59 * mDuff 's eyes hurt, and it's all sproingie's fault.

17:59 ordnungswidrig: hiredman: It doesn't as doesn't the servlet api. At least jetty doesn't. Ring middleware sounds right.

18:00 me goes to bed now.... enough parentheses for today.

18:00 mtm: my dreams have been in s-expressions lately...

18:08 savanni: I had one of those recently.

18:15 rhickey: hiredman: for what purpose?

18:28 cemerick: rhickey: it sounds like the language summit went swimmingly. Somehow I missed that you were giving the keynote...

18:29 rhickey: cemerick: It went really well, great roomful as was last time. I think the keynote was appropriately provocative and well received

18:30 cemerick: yeah, I think just the right number of lambs were sacrificed (at least judging from the slides, etc)

18:30 mtm: is the video of your keynote available yet?

18:36 cemerick: I've been very sad that the ILC videos haven't made it off their tapes, etc.

18:40 rhickey: And the state/identity talk from QCon

18:42 cemerick: rhickey: I take it you haven't heard anything about either of those?

18:42 I wish the ILC had charged $500 a head or something and then had plenty to cover immediate professional dubbing of the tapes, etc.

18:43 rhickey: I wouldn't hear, they just appear. I have no idea how they schedule the releases

18:43 hiredman: rhickey: 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:43 rhickey: hiredman: why does it need to be an agent?

18:44 there are lots of particular semantics of agents you might not be able to deliver on top of invokeLater

18:45 hiredman: like what?

18:47 from 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:47 rhickey: I still don't see why it needs to be an agent

18:47 hiredman: so I can use send and send-off

18:48 rhickey: so, right there, send-off can block, is that ok on the swing thread?

18:48 hiredman: it unifies interacting with the event dispatch thread in an async way with clojure's other async construct

18:49 rhickey: send blocks on the thread sending the action doesn't it?

18:49 rhickey: no

18:50 send and send-off always return immediately

18:50 a blocking action will block the thread pool thread

18:50 hiredman: oh, right

18:51 but that is do different than invokeandwainting a looping Runnable

18:51 or looping inside an agent action

18:51 rhickey: so send-off provides additional threads when needed, the event thread doesn't

18:51 not looping, blocking

18:52 hiredman: a looping action that doesn't complete would block

18:52 rhickey: block on IO in event thread - big no no

18:52 hiredman: I am aware

18:53 rhickey: so the semantics are simply not the same

18:53 making it quite wrong to reuse the calls

18:53 however similar it may feel to you

18:53 hiredman: :(

18:53 rhickey: sorry

19:19 cemerick: it's interesting that the NetBeans project (which is GPL and CDDL) doesn't require contributor agreements of any kind.

19:20 hiredman: http://www.netbeans.org/about/legal/ca.html <-- orly?

19:21 cemerick: hiredman: heh, OK, but they're taking my patches without my signing anything

19:22 hiredman: maybe the assumed you signed it?

19:22 cemerick: ha

19:22 well, maybe.

19:22 I don't care about my rights in this circumstance at all, but I hope they don't get in trouble for it.

19:24 actually, 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:25 fsm: is there anywhere a todo list for contributing to clojure?

19:26 i would be happy to contribute even some grunt work, documentation tidying, that kind of thing

19:26 technomancy: fsm: there are tickets on assembla; not sure if they include tidying-up work

19:26 ~assembla

19:26 cemerick: fsm: http://clojure.org/contributing

19:26 clojurebot: assembla is http://www.assembla.com/spaces/clojure

19:27 fsm: well, any mundane stuff really

19:27 cemerick: fsm: man, where were you when Chousuke and I manually moved the backlog to assembla?! ;-D

19:29 fsm: its a long time since i had enthusiasm about writing code, so i want to put back some effort

19:54 somnium: anyone who might be able to help with compojure/appengine? (or possibly just jetty + compojure servlet)

Logging service provided by n01se.net