#clojure log - Apr 24 2008

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

0:13 beau: hey guys

0:14 just wanted to say that I've recently discovered Clojure and find it exciting

0:14 I like the idea of combining my depth in Java with my passion for lisp

0:15 thanks for all the hard work rhickey

6:52 leafw: hi all

6:52 I am trying to build an command line interface for clojure

6:52 I tried to emulate the Repl.java

6:53 using PipedReader and PipedWriter to pass text directly to the LispReader

6:53 but the latter just blocks

6:53 essentially I am looking for the equivalent of PythonInterpreter.exec( String code )

6:54 but there is only a Compiler.eval(Object ..) which I think expects tokens

8:17 cgrand: leafw: (defn compile [s] (eval (read (new java.io.PushbackReader (new java.io.StringReader s)))))

10:48 rhickey_: Chouser: thinking about:

10:49 (let [{\: [a b c]} {:a 1 :b 2 :c 3}] [a b c])

10:49 (let [{\" [a b c]} {"a" 1 "b" 2 "c" 3}] [a b c])

10:49 (let [{\' [a b c]} '{a 1 b 2 c 3}] [a b c])

10:56 i.e. (let [{:keys [a], :strs [b], :syms [c]} {:a 1 "b" 2 'c 3}] [a b c]) becomes:

10:56 (let [{\: [a], \" [b], \' [c]} {:a 1 "b" 2 'c 3}] [a b c])

10:57 Chouser: yeah, you're using the punctuation instead of the name abbreviation.

10:57 It's more succinct, certainly.

10:57 rhickey_: I also like: (let [{:= [:a "b" 'c]} {:a 1 "b" 2 'c 3}] [a b c])

10:57 which just suffers from not using symbols

10:57 Chouser: right

10:58 rhickey_: but reads best IMO, is shortest, and allows :as

10:58 Chouser: none of these are necessarily exclusive.

10:59 := in particular seems like a nice complement for cases were you don't mind not having the literal symbol.

10:59 I don't mind the \: puncutation, that at first glance [{\' looks a little scarey.

11:00 "though at first"

11:02 using \: instead of :syms is pretty cute. like a punctuation pun.

11:03 rhickey_: \: would be :keys

11:04 Chouser: oh, sorry, right.

11:04 rhickey_: actually symbols wouldn't need quotes with :=

11:04 (let [{\: [a], \" [b], \' [c]} {:a 1 "b" 2 'c 3}] [a b c])

11:04 (let [{:= [:a "b" c]} {:a 1 "b" 2 'c 3}] [a b c])

11:05 Chouser: yes, but using symbols as map keys is not the most common usage.

11:06 rhickey_: not for hand-coded maps, but definitely will occur in data-driven maps, parsers etc

11:06 Chouser: (let [{:= [:a :b :c]} ...]) is more likely

11:06 rhickey_: true the mixed example is least fair

11:06 (let [{\: [a b c]} {:a 1 :b 2 :c 3}] [a b c])

11:06 (let [{:= [:a :b :c]} {:a 1 :b 2 :c 3}] [a b c])

11:07 Chouser: do you dislike having \: \" \' as well as := ?

11:07 * rhickey_ is trying to avoid a destructuring mini-language

11:08 Chouser: having the literal symbols visible is probably more important to me than a few extra keystrokes here or there.

11:08 heh. I think :as is the first slippery step down that particular slope.

11:09 rhickey_: by literal symbols you mean a b c, regardless if they came from strings/keywords/symbols?

11:11 Chouser: Right, as provided by the :keys and \: syntax options, as opposed to {:= [:a]}

11:12 My editor's search function and syntax highlighter can help me find the former, but (currently) fails for the latter.

11:12 I assume that would be try of most editors.

11:12 true of most editors. (sorry I apparenly can't type)

11:13 rhickey_: what does it do for CL keyword args, which only appears as keywords in the defun?

11:14 (not denying editor complexity issues, though)

11:14 Chouser: oh, I imagine it similarly fails. I haven't done much CL.

11:14 rhickey_: as far as clarity, which makes it clearer you are matching keys when the map is opaque:

11:14 (let [{\: [a b c]} amap] [a b c])

11:14 (let [{:= [:a :b :c]} amap] [a b c])

11:15 (others please chime in :)

11:17 or strings:

11:17 (let [{\" [a b c]} amap] [a b c])

11:17 (let [{:= ["a" "b" "c"]} amap] [a b c])

11:17 * rhickey_ hates typing in strings, prefers former in this case

11:19 Chouser: might get more input on the google group

11:19 rhickey_: \= or \' for symbols:

11:20 (let [{\= [a b c]} amap] [a b c])

11:20 (let [{\' [a b c]} amap] [a b c])

11:20 jteo: this is getting perlish.

11:21 Chouser: so what about (let [{:strs [a b c]} amap] [a b c])

11:21 less perlish?

11:22 jteo: yup

11:26 rhickey_: head-to0

11:26 head-to-head:

11:26 (let [{:keys [a b c]} amap] [a b c])

11:26 (let [{\: [a b c]} amap] [a b c])

11:26 (let [{:= [:a :b :c]} amap] [a b c])

11:28 jteo: i vote for :keys

11:28 Chouser: (let [{foo "f", bar "b", \: [a b c]} amap] [foo bar a b c])

11:28 \: is maybe less scarey when not packed in next to [{

11:29 rhickey_: editor distinguishing char literal would help

11:33 Chouser: what does that mean?

11:34 cgrand: I prefer :=

11:34 Chouser: oh, having \: colored differently than [{ ?

11:36 rhickey_: Chouser: right

11:36 MarkJP: the fact that clojure has emoticons is awesome :p

11:36 rhickey_: cgrand: even in the string case?

11:37 (let [{:= ["a" "b" "c"]} amap] [a b c])

11:38 I like getting rid of all those """"

11:43 cgrand: I prefer {:= [a "b" :c]} to {:syms [a] :strs [b] :keys [c]}, find it easier to read -- I don't mind entering strings (... and my editor don't let them "leak").

11:44 vincenz: cgrand: schmemacs?

11:44 why not simply

11:44 {a b c}

11:45 cgrand: vincenz: no a quick and dirty eclipse plugin

11:45 vincenz: (let [{a b c} amap] [a b c])

11:47 cgrand: vincenz: this is ambiguous: do you want keywords, symbols or strings as key values? (plus you can't have an odd number of atoms between { and })

11:47 vincenz: oh

11:47 cgrand: the latter is false

11:47 cgrand: this is a binding not an expression

11:47 different syntactical {}

11:48 cgrand: ah?

11:48 vincenz: (let [binding exp] exp)

11:49 but yes, you mke a good point about different keytypes :)

11:49 (let ({:a => a, "foo" => b, 1 => c} amap) [a b c])

11:51 cgrand: well I dunno about clojure, but generically, one is an exp, the other is a binding, so I fail to see why the cconstraints of an exp should have any influence on the constraints of a binding

11:51 rhickey_: vincenz: this is a lisp, so we are not inventing raw syntax but defining the interpretation of data structures, so you must propose a valid Clojure data structure

11:51 Chouser: even so, you'd still want a way to rename hash keys on their way to becoming local bound symbols.

11:51 vincenz: (let ({:a a "foo" b 1 c} amap) [a b c])

11:51 ?

11:52 rhickey_: a map itself can be a binding, they nest

11:52 vincenz: Chouser: I thought the wohle idea above was a shortcut syntax to not have to repeat

11:52 rhickey_: how does this not nest?

11:52 (let ({:a {:b a} "foo" b 1 c} amap) [a b c])

11:53 {key pat ..}

11:53 rhickey_: that is the current destructuring support already

11:53 vincenz: oh

11:53 * vincenz shuts up

11:54 rhickey_: want to avoid {a :a b :b c :c}, e.g. when the binding names would be the same

11:54 vincenz: why not wrap a macro around it?

11:55 (let ((some-macro-name a b c) amap) [a b c])

11:55 or does the let-macro already desugar patterns?

11:56 rhickey_: we are discussing the underpinnings of the destructuring support used by many macros, including let itself

11:57 vincenz: Well obviousy I'm commenting as an outsider here, but aren't you over-sugaring the core then?

11:57 rhickey_: cgrand: yes, {:= [a "b" :c]} wins in the mixed case for brevity, and does IMO have the greatest clarity as to what is going on

11:58 vincenz: the pervasive destructuring is quite useful - building it into let means getting it for free in anything built on let - virtually everywhere, and it will all work the same

11:59 vincenz: I won't argue against destructuring, given my roots :) Though I really wonder whether it's not possible to do this in the macro-system instead of in the language.

12:00 Chouser: this is all implemented in boot.clj

12:02 vincenz: Chouser: 'destructure' ?

12:02 Chouser: you found it!

12:21 rhickey_: vincenz: this is the macro system, compiler is unaffected

12:36 cgrand: Since lists are not valid binding forms, would allowing (let [(custom-destructuring-macro x y) data] ...) be a bad idea?

12:37 rhickey_: lists are being saved for some future extension

12:41 cgrand: ok

12:42 vincenz: rhickey_: ah I see how it works now

12:43 rhickey_: the vector is a literal, which is then trasnmuted to a pattern

12:43 * vincenz thought the patterns were native

12:44 cgrand: rhickey, could the else form in if-let be optional?

12:53 Chouser: cgrand: you want when-let

12:59 cgrand: chouser: I know when-let but as I work on some piece of code, I change an if into an if-let, work on something else, delete the else form and... my code doesn't compile anymore, I go back and change if-let in when-let... and when-let smells like a do :-)

13:00 To sum up: if/when and if-let/when-let are not "symmetric" and that annoy me

13:00 annoys

13:05 Chouser: ah

13:06 just use cond for everything. ;-)

13:08 oh, I see. 'if' allows you to skip the else, but 'if-let' doesn't. Yeah, that doesn't seem right.

13:25 rhickey_: cgrand: I will look at that

13:25 cgrand: thanks

19:24 drewr: How do I extract a class constant?

19:24 (. Collection EMPTY_LIST)

19:25 --> CompilerException

19:25 Probably because the reader can't figure out what EMPTY_LIST is.

20:28 Chouser: drewr: (. java.util.Collections EMPTY_LIST)

22:59 blbrown: hello

23:00 drewr: blbrown: Hi.

23:03 blbrown: drewr: http://groups.google.com/group/clojure/browse_thread/thread/ca468c3548b7d16d do you know anything about this.

23:07 drewr: Hm.

23:08 I would point you to Rich's ant.clj. It uses a JFrame.

23:09 blbrown: this might help, I am looking at this example: http://clojure.sourceforge.net/features/jvm_hosted.html

23:10 drewr: Yeah, I've played around with that.

23:20 blbrown: hmm, his example does the same thing....if you run with 'clj theexample.clj'

23:21 drewr: Let me know what you figure out.

23:22 blbrown: it is probably bad practice, but I guess I will just add a loop; maybe I am supposed place with the agents or something

Logging service provided by n01se.net