#clojure log - Sep 30 2008

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

0:02 arohner: is there any introspection that can be done on local variables that a macro creates?

0:03 I'm looking at a macro that does (let [foo (func-call)] (your-code))

0:03 aside from reading the macro source, is there any way to figure out where foo came from?

0:03 i.e. I can't do (meta (var foo)) because it's a local variable

0:13 * abrooks hopes rhickey makes it home safely after an excellent talk in Boston this evening

1:04 abrooks: albino: Thanks for pointing out Nailgun. A couple of weeks ago I drew up plans to do a similar thing only using Unix domain sockets (on platforms that support it) instead of TCP sockets. Unix domain sockets have some neat features such as being able to actually verify uid/gid over the socket securely and the extra nifty ability to send file descriptors via the socket. (Unix domain sockets are only acessible on the same host.)

1:05 With the ability to send file descriptors, the IO has zero overhead -- the "remote" process actually uses the same file descriptors directly.

1:07 There are certain things (process niceness, capabilities (on Linux and others), process quotas, etc.) which cannot be sent across the socket but it's fairly reasonable that one can have near zero startup overhead and truly zero runtime overhead.

11:23 blackdog: http://blogs.azulsystems.com/cliff/2008/09/jvm-language-su.html

11:24 some good comments from cc - "Clojure spits out bytecodes that look really nice. The purely functional data-structures also look really nice; and the STM scaled surprisingly well. I definitely need to do some coding with it."

11:25 rhickey: also: "I ran Clojure's STM Traveling Salesman Problem using 600 worker 'ants' to optimize the path. It ran straight-up without a hitch, no tweaks - and with great scaling"

11:27 blackdog: could be good for the front page of clojure.org

11:27 rhickey: he used that Clojure TSP program to demo his super-cool profiling tools - very neat to see Clojure bouncing 600 lines of his CPU meters

11:28 It's still early days in testing STM at these scales, but Cliff's a great resource and very helpful

11:28 blackdog: a great start! not that i'll ever use a box like that :P

11:28 abrooks: rhickey: Glad to see you made it home safe! Sorry you were kept there so long. Did you get home before 1am?

11:29 rhickey: abrooks: just after - no problem driving, and was happy to stay and talk. Such a great audience!

11:30 abrooks: I brought five guests and they all loved it!

11:31 pjb3: Did anyone record the talk last night?

11:31 rhickey: Met Dan Weinreb. Gerald Sussman, Alan Bawden. Last week I had Guy Steele in the audience - fun to connect with these guys who started it all

11:32 pjb3: I did a screen+audio capture and someone videotaped

11:32 pjb3: rhickey: cool

11:33 blackdog: did you have any awkward or standout questions last night ?

11:34 abrooks: rhickey: How did last night the group size rougly the same size audience as previous talks?

11:34 er....

11:34 rhickey: I think the audience was genuinely interested in understanding Clojure rather than challenging it

11:34 abrooks: rhickey: How did last night's group size compare with the audience size from previous talks?

11:34 leafw: rhickey: because clojure is not just an incremental improvement over java.

11:34 walters: it seems pretty beyond challenge after looking at it for more than a few seconds, IMO

11:35 abrooks: leafw: Because Clojure's not an incremental improvement over Lisp...

11:35 blackdog: i noticed ola bini seemed to feel uncomforatable with clojure's new structures, which prompted my question if the 'old school' were cool

11:35 abrooks: leafw: This crowd *knows* that Lisp is an improvement over Java. ;-)

11:35 leafw: abrooks: libraries and legacy code, thye matter a lot.

11:36 abrooks: leafw: Certainly. One of the many great things about Clojure.

11:36 leafw: all of a sudden, we can have both.

11:36 (lisp and libraries)

11:37 rhickey: blackdog: I didn't get to finish my conversation with Ola about that, but I think if he saw how easy it is to handle the data structures uniformly in Clojure he might change his mind: e.g. (into (empty coll) (map f coll)) works for anything in Clojure

11:37 abrooks: leafw: CL has great libraries but they're have less relevance to the current universe.

11:40 rhickey: blackdog: I think the oldest of the old school were perhaps the most receptive - they remember Lisp before standardization when everyone had their own dialect and there was lots of variety and innovation

11:41 blackdog: fantastic, you hit a sweet spot for sure,

11:42 rhickey: I had so much fun - this was the audience best suited to 'getting' Clojure right away, as they already 'got' Lisp and I could presume that in my talk

11:45 Chouser: def-aset generates calls to Array static methods like setLong. Would it be acceptible for it to call RT.aset instead?

11:47 rhickey: abrooks: crowd was smaller than JVM languages summit, larger than the Java user group I did in June

11:48 abrooks: Oh, I wasn't really counting the JVM languages summit. Those folks weren't there just for Clojure. In 2010 they will be. :-)

11:49 rhickey: abrooks: It was the biggest user group so far

11:50 abrooks: Great. I heard it was over sixty. Thirty-five had registered.

11:51 walters: i wonder whether that large group that came in after 6pm was together in some way, like all from some class

11:57 danlarkin: oooo I can't wait for a new video

12:03 earthvssoup: here here

12:05 rhickey: It's over 3 hours...

12:05 * rhickey is long-winded

12:06 rhickey: actually there were lots of good questions, if they came out in the audio it will be great

12:07 danlarkin: fantastic

12:16 earthvssoup: Heck, I'd watch 3-hours just to see the Emacs-Fu. ;)

12:20 leafw: [rhickey: I make it customary to repeat the questions, so everybody hears them through the microphone]

12:36 rhickey: leafw: yes, I keep telling myself to do that, but then forgetting...

12:47 Chouser: looks like JavaScript may be growing thread support after all: http://www.whatwg.org/specs/web-workers/current-work/

12:48 message passing for inter-thread communication

12:48 rhickey: saw that

12:49 I don't think they could support actual data sharing giving JS heritage, so offering an explicit API gets around that

12:49 Chouser: right

12:51 rhickey: A Boston Lisp Meeting report: http://xach.livejournal.com/#entry_191581

12:53 Chouser: I've been getting reports all morning from my half-dozen friends that were there.

12:53 everyone enjoyed it

12:53 danlarkin: http://search.twitter.com/search?q=clojure lots of positive experiences on twitter too

12:54 earthvssoup: @Chouser. Thanks for the tips on my On Lisp -> Clojure project. Much appreciated.

12:54 baetis-fly: anyone know if a video exists of the boston lisp presentation on clojure exists?

12:54 Chouser: earthvssoup: sure, looks like a cool project.

12:55 earthvssoup: Thanks. That remains to be seen. ;)

12:55 Chouser: baetis-fly: nothing online yet, but there's hope.

12:55 * baetis-fly crosses fingers

12:56 rhickey: earthvssoup: yes, good project. You should try to stay functional when possible, rather than copying imperative things from CL, that will have the most value. Stuart Halloway has been doing the same (translating to FP style) in covering the PCL stuff, with much success

12:58 earthvssoup: rhickey: I am still trying to find my way out of my imperative nature. It's slow going for the first couple of chapters, but I'm confident that I'll come around.

13:02 danlarkin: earthvssoup: it's always helped me to think "what do I want" rather than "how do I get it"

13:55 earthvssoup: danlarkin: Thanks, I will keep that in mind.

17:08 StartsWithK: if i have macro like (doto x (something1 args) (something2 args)), i would like to (find-var something1) and (find-var something2) and if something exists and is macro, evoluate it in a same way (clojure/doto) evoluates first argument before it includes it in rest of the macro

17:08 is something like this possible?

17:18 hoeck: StartsWithK: so you want a macro that treats other macros specially?

17:19 StartsWithK: something like that

17:19 hoeck: StartsWithK: or do you just want to expand nestet macros?

17:19 StartsWithK: hmm

17:19 expand i think

17:19 if that is right term

17:19 ok, one 'example'

17:20 hoeck: the thing that `macroexpand' does

17:20 StartsWithK: (doto (JButton.) (on :action-performed (fn [e] (println "you clicked on button"))))

17:20 this is what i will put on firs version

17:20 where (on) is some sort of 'patch' multimetod that my doto macro will use

17:21 hoeck: ah, i see

17:21 StartsWithK: but what i wan is (doto (JButton.) (on :action-performed [e] (println "you clicked..")))

17:22 so, on must be a macro in second example and it should expand to firs example before i use it in

17:22 actualy :action-performed is defalut so it will be even shorter as (on [e] ...)

17:23 hoeck: so you want to roll your own doto macro?

17:23 StartsWithK: yes

17:24 i mean, i have one now

17:24 this is my idea of 'patch' system that i would like to include in it

17:24 Chouser: I think you could approach two ways -- either make "on" a global macro of its own, or have doto walk through its args looking for (on ...)

17:25 actually, this first won't work. so you could try the second. ;-)

17:25 StartsWithK: Chouser: i was thinking i would lookup for var, and see does it have macro metadata on it

17:26 or maybe on some metadata of my own like :dotoexpand true

17:27 Chouser: (meta (resolve foo)) where foo is a local that contains the symbol you're examining

17:27 StartsWithK: i pasted this yesterday http://pastebin.com/d3bb8978

17:27 at the end is example of extended doto for now

17:28 now what i want are two more things, first is that all (method args) are routed to (defmulti patch) that will first try to find multimethod for given class with given method name and execute it instead of classes method

17:29 and second thing are the macros inside doto as i described them now

17:29 Chouser: I think "resolve" is what you're looking for to find the var for a symbol

17:30 (:macro (meta (resolve f))), like you have (keyword? f)

17:31 StartsWithK: yes that is what i need

17:32 but, how will i expand it

17:32 that part bugs me even more

17:34 Chouser: you probably don't want to expand it yourself, but rather drop it into your output, where it can be expanded for you by the compiler

17:34 if your macro produces (do .... (foo ...) ...), and foo is a macro, it'll get expanded for you

17:36 StartsWithK: when i process doto args, i will in the end transform (doto x (meth1 a) (meth2 b)) to something lik (. x meth1 a) (. x meth2 b)

17:36 but if i don't expand on macro ill get (. x on ...)

17:37 Chouser: right, so don't do that.

17:37 When you identify it as a macro, produce (on x ...) instead of (. x on ...)

17:37 StartsWithK: oh, i see

17:37 yes

17:38 i wasn't thinking i can just expand it in different way :)

17:39 Chouser: you know, I don't really like how doto has you specify methods without any .

17:39 you could make a pretty simple macro that worked instead like (doto obj (.meth1 a) (.meth2 b))

17:40 then you wouldn't have to do any special handling to get macros or even regular functions in there

17:40 (doto obj (.meth1 a) (on foo) (.meth2 b))

17:40 the doto macro would just insert obj as the 1st arg of each, and either get a method call, or a macro, or whatever.

17:41 kinda like -> except for all applying to one thing instead of chaining.

17:42 StartsWithK: true, that would be much easyer way to do it

17:42 but then i wouldn't be compatible with clojure/doto

17:43 Chouser: I actually think it'd be easier to read than clojure/doto

17:43 yeah, good point. you might choose to name it differently

17:43 or talk rhickey into accepting your syntax instead. :-)

17:43 StartsWithK: :)

17:44 i will bug him when this monster is finished :)

17:45 i would like at least something like (method+) syntax

17:45 i find i do a lot of (addOption ..) (addOption ..) ...

17:48 Chouser: (with-arg foo (a) (b)) --> (do (a foo) (b foo))

17:48 (with-cmd .foo (a) (b)) --> (do (.foo a) (.foo b))

17:49 each would be simple and together would buy you doto and method+ functionality.

17:52 StartsWithK: let me sketch something bigger to demonstrate

17:53 H4ns: hi - i'm new to clozure. what is a [B@4a5afcb1 (something binary i guess) and how can i decode that into a string, possibly specifying the character set?

17:53 clojure

17:54 danlarkin: H4ns: how did you get it?

17:54 H4ns: danlarkin: i got it from the http client.

17:54 rhickey: [B is a byte array

17:56 danlarkin: maybe run seq on it?

17:56 StartsWithK: Chouser: http://pastebin.com/d5b2bdf6e

17:56 rhickey: String has a ctor from byte array, so (String. ba)

17:56 optional second arg is a string naming a charset

17:56 (String. ba charset-name)

17:56 H4ns: rhickey: very cute, thanks! i've seen your talk yesterday, coming from cl.

17:57 rhickey: H4ns: cool - do you know Java?

17:58 H4ns: rhickey: only a tiny bit, i'm mostly common lisp, coming from perl, c++, c

17:58 rhickey: you might want to bookmark: http://java.sun.com/j2se/1.5.0/docs/api/ then

17:59 H4ns: rhickey: but i've written applets and small applications, so i'll find my way through. i'll just have to adopt to the notion that many primitive things are just java apis.

17:59 rhickey: bookmarked, thanks

17:59 rhickey: H4ns: ok - I'm sure you'll get up to speed in no time, lots of helpful folks here and on the google group too

18:00 H4ns: rhickey: ok - thanks again for the warm welcome. yesterday morning i had no hope for lisp, that has changed a little now :)

18:02 where do i find clojure.xml?

18:04 ahj.

18:04 never mind.

18:04 ppjt: Hi all; I'm playing with, & have aped successfully for use in macros, the `(let ~'[i 5] ...) form -- i.e. the ~', quote-unquote part -- but don't think I could explain it if I had to. I see that without it the variable, say, in the let binding above would be qualified with a namespace, but I'm still not exactly sure why.

18:05 Does anyone mind explaining?

18:06 [unquote-quote, that is]

18:08 H4ns: hm. (clojure.xml/parse "http://planet.lisp.org/rss20.xml") seems to end up in an unhandled exception when the server closes the connection. expected? better to slurp using the http client (which works) and then create a stream from that?

18:11 danlarkin: H4ns: (clojure.xml/parse "http://planet.lisp.org/rss20.xml") works for me

18:13 H4ns: danlarkin: i'm ending up in the slime debugger, (condition-case (error (slime-net-read ... - slime fairly recent, clojure from cvs, java 1.5 downloaded today

18:13 i'll try without slime

18:13 ppjt: Me too; what's the exception you get, H4ns? A java.net.something-or-other?

18:14 H4ns: if i interpret the message correctly, it is actually slime that fails, no java in there, but a net-read-error. i'll try without first.

18:14 yes, slime problem. is slime not really the way to go? what do others here use?

18:15 might also be related to the fact that i'm using windows. if that is uncommon, i'll use something else.

18:16 ppjt: I'm not an emacser, but I believe someone has worked up a slime-like thing called swank-clojure. Just a sec...

18:16 H4ns: ppjt: that is what i use.

18:17 ppjt: i've downloaded it fresh from git

18:17 fyuryu: I use clojure-mode for emacs, no problems so far

18:17 danlarkin: H4ns: slime is what rhickey uses too I believe

18:17 H4ns: fyuryu: how do you evaluate? just the bare repl in a inferior shell and copy and paste?

18:18 ppjt: Yeah, I think a lot of folks are having success w/ swank-clojure

18:18 fyuryu: H4ns: no, there are kb combos for that

18:18 H4ns: for sending code to the repl, that is

18:19 H4ns: okay, maybe windows is the culprit. i'll move to unix, thanks so far. the parsing and http clienting looks very nice, so i'll spend some time to get my environment straight :)

18:19 fyuryu: H4ns: i'm on windows too

18:20 danlarkin: could it be that code in H4ns' pull of swank-clojure has a bug and fyuryu's does not?

18:21 H4ns: danlarkin: could also be that my slime/emacs is not the right version.

18:21 fyuryu: danlarkin: I don't use swank-clojure, just clojure-mode

18:22 danlarkin: ah

18:29 H4ns: thanks so far. seems i need to tweak some more, bbl.

18:31 ppjt: Anyone familiar with the `(let ~'[i 5] i) -- i.e. the ~' part -- trick?

18:35 hoeck: ppjt: its to avoid the `i' becoming a namespace-qualified symbol

18:36 ppjt: hoeck: Do you know how it does that, exactly?

18:40 hoeck: it evaluates the quoted symbol and inserts that result into the macroexpansion

18:43 the ~ means to evaluate the following expression

18:43 and in case of `'foo, the following expr is 'foo

18:44 evaluating to foo

18:44 ppjt: hoeck: why doesn't the resulting symbol, then, get namespace-qualified?

18:45 hoeck: cause its evalutated at the expansion time of the macro

18:45 ppjt: I think that's where I'm dropping out -- when does namespace-qualification happen in normal evaluation, & why wouldn't this symbol be subject to same?

18:46 hoeck: namespace-qualification happens only in backquote as far as i know

18:46 StartsWithK: hoeck, Chouser, thanks for help

18:47 ppjt: hoeck That makes sense, based on my REPL experiments...

18:48 hoeck: yeah, just try `(foo bar), `(foo ~'bar) and (let [bar [1 2]] `(foo ~bar))

18:49 ppjt: So, though everything inside a backquoted expression is _quoted_, the quote-unquote extra bit serves to avoid the ns-qualification stuff that comes as well w/ backquoting

18:51 hoeck: actually, its an unquote-quote :)

18:51 ppjt: Right!

18:53 Though it makes more sense to think of the act of quoting, then unquoting that quote -- in right-to-left evaluation order that lisp works in...

18:53 At least makes more sense to me

18:54 hoeck: Do you know the utility of backquote's namespace-qualifying?

18:57 hoeck: when you define a macro in namespace a and expand it in namespace b, it avoids that the expanded expression does shadow symbols in namespace b

18:58 ppjt: Right -- makes good sense

18:59 hoeck: without this you would need to manually namespace-qualify each symbol

18:59 or hope that no shadowing occurs

18:59 ppjt: Yeah -- would make for either tedious or bug-laden code

19:00 hoeck: right

19:00 ppjt: So is the quote-unquote (or vice-versa) technique the standard way to, say, set up let bindings inside of a backquoted expression in a macro?

19:00 Or are there others?

19:01 hoeck: i guess its the only one

19:02 ppjt: I don't have time to look through boot.clj at the moment, but that'd be the place to investigate; I'll do so tonight...

19:02 hoeck: but you can build lists directly with (list 'let (vector 'i 5) ...)

19:03 ppjt: Oh yeah, good point

19:03 Though, cause of lost readability there, I'd gladly take the ~' option

19:04 H4ns: can anyone here confirm that slime works on windows? i'd like to know that i'm not aiming for something too exotic

19:04 hoeck: backquote is basically an abbreviation, like quote '

19:05 ppjt: With the semantics of ', plus the ability to use ~, right?

19:06 hoeck: H4ns: i have a windows box at work, but I'm only using ilisp, not slime, could investigate tomorrow

19:06 H4ns: hoeck: so there is an ilisp backend? i would consider that, too.

19:08 hoeck: ppjt: yes, basically, + X times magic like doing namespace-qualif. in clojure and other things I don't know in cl

19:08 shoover: H4ns: yes, I use swank-clojure on a couple Windows machines. Make sure you have recent slime from CVS, at least from this month

19:09 H4ns: shoover: ah, thank you - any special emacs version, or stock windows emacs 22?

19:10 hoeck: H4ns: i build this one myself, but i want to use slime soon too, on windows and linux

19:11 H4ns: hoeck: ok - i'll first try an updated slime and then try ilisp if i fail. thanks!

19:11 ppjt: hoeck: An alternative to ~' in backquoted let expressions: `(let [i# 5] i#)

19:11 Another bit of ` magic, it seems

19:11 shoover: H4ns: works with stock 22.2 and latest patched emacs 23 from http://ourcomments.org/cgi-bin/emacsw32-dl-latest.pl

19:16 H4ns: shoover: thanks, updating slime fixed my problem.

19:16 ppjt: hoeck: Gotta run -- thanks

19:16 hoeck: ppjt: np

19:44 H4ns: what ways to process xml are popular in clojure? i've looked at clojure.xml and cxml and there is java's facilities. i need something that lets me extracts elements out of a dom easily, preferably using an xpath/sxpath like syntax to specify what elements interest me

20:21 rhickey: H4ns: Chouser has an xpath-like library in clojure-contrib https://sourceforge.net/projects/clojure-contrib called zip-filter

20:22 video from last night converting right now

20:23 H4ns: rhickey: i've also read what you wrote about 'xml is just data', trying to bend my head around that. i'll look at zip-filter, thanks.

20:24 * H4ns applauds for the comment macro

20:33 H4ns: what is the proper way to quit clojure?

20:35 rhickey: H4ns: (System/exit 0)

20:36 H4ns: *bow*

21:13 danlarkin: rhickey: will you upload it to blip this evening?

21:23 rhickey: danlarkin: no, tomorrow, conversion to Flash takes over 8 hours

21:24 danlarkin: rhickey: I suppose I can wait that long...

22:05 acharlton: ?

22:09 Hi, all. Is there any reason why a piece of code would run differently in the repl than straight from the command line (ie. clojure.lang.Script)?

22:12 rhickey: acharlton: run differently in what way?

22:17 acharlton: I have a ref that is a map that holds other maps. As far as I can tell, when I run my program through clojure.lang.Script it adds an extra, duplicate map to that ref. This does not happen in the REPL.

22:22 That's not really the whole story, since there are some functions manipulating the ref that seem to be creating the duplicate, but why would it only be happening with clojure.lang.Script?

22:26 Chouser: you run the same .clj file, the only difference being the class you name on the java command-line?

22:26 acharlton: That's right.

22:29 Well, I suppose I haven't actually run the file through java command-line for the REPL instance. I've started the REPL and then (load-file "thesamefile.clj")

22:29 Chouser: hm.

22:34 acharlton: Huh. I just tried loading the file with the java clojure.lang.Repl, and the thing that happened with clojure.lang.Script happened again. It only seems to work properly (in the way I intended it - my code may very well be faulty) when I start the actual REPL and (load-file)

22:39 Chouser: you could paste your code, if you want.

22:54 acharlton: I'm not sure if it's worth the trouble. My code is actually broken (upon further inspection), and it's quite convoluted. I was just a little freaked out that it runs differently from inside the REPL.

23:12 Alright. There was no mysterious map duplication. It was an accidental byproduct of a function. I'm still a little curious about why the results would differ inside and out of the REPL, though. Any insight?

23:13 Or was it a freak of nature?

23:14 rhickey: there should be no difference, unless prior to load-file in the repl you manually set up some environment not present when run as a script

23:17 acharlton: I'm afraid not. (load-file) was the one and only command run in the repl.

23:19 rhickey: acharlton: Script just calls loadfile, so it shouldn't be different

23:20 acharlton: That's messed up, then.

23:20 rhickey: but if you can reproduce I'll chase it

23:33 acharlton: Well, it doesn't seem to affect me in any real way, and it does seem to be a weird fringe case. I'm not even sure if the ref itself was differet, I was just basing my assumptions off of the visual feedback of my program.

23:35 rhickey: if you see it again, grab it by the tail

23:36 acharlton: Heh. Alright.

23:36 Thanks a lot for the help. Have a good night.

Logging service provided by n01se.net