#clojure logs

2008-04-24

00:13beauhey guys
00:14beaujust wanted to say that I've recently discovered Clojure and find it exciting
00:14beauI like the idea of combining my depth in Java with my passion for lisp
00:15beauthanks for all the hard work rhickey
06:52leafwhi all
06:52leafwI am trying to build an command line interface for clojure
06:52leafwI tried to emulate the Repl.java
06:53leafwusing PipedReader and PipedWriter to pass text directly to the LispReader
06:53leafwbut the latter just blocks
06:53leafwessentially I am looking for the equivalent of PythonInterpreter.exec( String code )
06:54leafwbut there is only a Compiler.eval(Object ..) which I think expects tokens
08:17cgrandleafw: (defn compile [s] (eval (read (new java.io.PushbackReader (new java.io.StringReader s)))))
10:48rhickey_Chouser: thinking about:
10:49rhickey_(let [{\: [a b c]} {:a 1 :b 2 :c 3}] [a b c])
10:49rhickey_(let [{\" [a b c]} {"a" 1 "b" 2 "c" 3}] [a b c])
10:49rhickey_(let [{\' [a b c]} '{a 1 b 2 c 3}] [a b c])
10:56rhickey_i.e. (let [{:keys [a], :strs [b], :syms [c]} {:a 1 "b" 2 'c 3}] [a b c]) becomes:
10:56rhickey_(let [{\: [a], \" [b], \' [c]} {:a 1 "b" 2 'c 3}] [a b c])
10:57Chouseryeah, you're using the punctuation instead of the name abbreviation.
10:57ChouserIt's more succinct, certainly.
10:57rhickey_I also like: (let [{:= [:a "b" 'c]} {:a 1 "b" 2 'c 3}] [a b c])
10:57rhickey_which just suffers from not using symbols
10:57Chouserright
10:58rhickey_but reads best IMO, is shortest, and allows :as
10:58Chousernone of these are necessarily exclusive.
10:59Chouser:= in particular seems like a nice complement for cases were you don't mind not having the literal symbol.
10:59ChouserI don't mind the \: puncutation, that at first glance [{\' looks a little scarey.
11:00Chouser"though at first"
11:02Chouserusing \: instead of :syms is pretty cute. like a punctuation pun.
11:03rhickey_\: would be :keys
11:04Chouseroh, sorry, right.
11:04rhickey_actually symbols wouldn't need quotes with :=
11:04rhickey_(let [{\: [a], \" [b], \' [c]} {:a 1 "b" 2 'c 3}] [a b c])
11:04rhickey_(let [{:= [:a "b" c]} {:a 1 "b" 2 'c 3}] [a b c])
11:05Chouseryes, but using symbols as map keys is not the most common usage.
11:06rhickey_not for hand-coded maps, but definitely will occur in data-driven maps, parsers etc
11:06Chouser(let [{:= [:a :b :c]} ...]) is more likely
11:06rhickey_true the mixed example is least fair
11:06rhickey_(let [{\: [a b c]} {:a 1 :b 2 :c 3}] [a b c])
11:06rhickey_(let [{:= [:a :b :c]} {:a 1 :b 2 :c 3}] [a b c])
11:07Chouserdo you dislike having \: \" \' as well as := ?
11:08Chouserhaving the literal symbols visible is probably more important to me than a few extra keystrokes here or there.
11:08Chouserheh. I think :as is the first slippery step down that particular slope.
11:09rhickey_by literal symbols you mean a b c, regardless if they came from strings/keywords/symbols?
11:11ChouserRight, as provided by the :keys and \: syntax options, as opposed to {:= [:a]}
11:12ChouserMy editor's search function and syntax highlighter can help me find the former, but (currently) fails for the latter.
11:12ChouserI assume that would be try of most editors.
11:12Chousertrue of most editors. (sorry I apparenly can't type)
11:13rhickey_what does it do for CL keyword args, which only appears as keywords in the defun?
11:14rhickey_(not denying editor complexity issues, though)
11:14Chouseroh, I imagine it similarly fails. I haven't done much CL.
11:14rhickey_as far as clarity, which makes it clearer you are matching keys when the map is opaque:
11:14rhickey_(let [{\: [a b c]} amap] [a b c])
11:14rhickey_(let [{:= [:a :b :c]} amap] [a b c])
11:15rhickey_(others please chime in :)
11:17rhickey_or strings:
11:17rhickey_(let [{\" [a b c]} amap] [a b c])
11:17rhickey_(let [{:= ["a" "b" "c"]} amap] [a b c])
11:19Chousermight get more input on the google group
11:19rhickey_\= or \' for symbols:
11:20rhickey_(let [{\= [a b c]} amap] [a b c])
11:20rhickey_(let [{\' [a b c]} amap] [a b c])
11:20jteothis is getting perlish.
11:21Chouserso what about (let [{:strs [a b c]} amap] [a b c])
11:21Chouserless perlish?
11:22jteoyup
11:26rhickey_head-to0
11:26rhickey_head-to-head:
11:26rhickey_(let [{:keys [a b c]} amap] [a b c])
11:26rhickey_(let [{\: [a b c]} amap] [a b c])
11:26rhickey_(let [{:= [:a :b :c]} amap] [a b c])
11:28jteoi vote for :keys
11:28Chouser(let [{foo "f", bar "b", \: [a b c]} amap] [foo bar a b c])
11:28Chouser\: is maybe less scarey when not packed in next to [{
11:29rhickey_editor distinguishing char literal would help
11:33Chouserwhat does that mean?
11:34cgrandI prefer :=
11:34Chouseroh, having \: colored differently than [{ ?
11:36rhickey_Chouser: right
11:36MarkJPthe fact that clojure has emoticons is awesome :p
11:36rhickey_cgrand: even in the string case?
11:37rhickey_(let [{:= ["a" "b" "c"]} amap] [a b c])
11:38rhickey_I like getting rid of all those """"
11:43cgrandI 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:44vincenzcgrand: schmemacs?
11:44vincenzwhy not simply
11:44vincenz{a b c}
11:45cgrandvincenz: no a quick and dirty eclipse plugin
11:45vincenz(let [{a b c} amap] [a b c])
11:47cgrandvincenz: 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:47vincenzoh
11:47vincenzcgrand: the latter is false
11:47vincenzcgrand: this is a binding not an expression
11:47vincenzdifferent syntactical {}
11:48cgrandah?
11:48vincenz(let [binding exp] exp)
11:49vincenzbut yes, you mke a good point about different keytypes :)
11:49vincenz(let ({:a => a, "foo" => b, 1 => c} amap) [a b c])
11:51vincenzcgrand: 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:51rhickey_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:51Chousereven so, you'd still want a way to rename hash keys on their way to becoming local bound symbols.
11:51vincenz(let ({:a a "foo" b 1 c} amap) [a b c])
11:51vincenz?
11:52rhickey_a map itself can be a binding, they nest
11:52vincenzChouser: I thought the wohle idea above was a shortcut syntax to not have to repeat
11:52vincenzrhickey_: how does this not nest?
11:52vincenz(let ({:a {:b a} "foo" b 1 c} amap) [a b c])
11:53vincenz{key pat ..}
11:53rhickey_that is the current destructuring support already
11:53vincenzoh
11:54rhickey_want to avoid {a :a b :b c :c}, e.g. when the binding names would be the same
11:54vincenzwhy not wrap a macro around it?
11:55vincenz(let ((some-macro-name a b c) amap) [a b c])
11:55vincenzor does the let-macro already desugar patterns?
11:56rhickey_we are discussing the underpinnings of the destructuring support used by many macros, including let itself
11:57vincenzWell obviousy I'm commenting as an outsider here, but aren't you over-sugaring the core then?
11:57rhickey_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:58rhickey_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:59vincenzI 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:00Chouserthis is all implemented in boot.clj
12:02vincenzChouser: 'destructure' ?
12:02Chouseryou found it!
12:21rhickey_vincenz: this is the macro system, compiler is unaffected
12:36cgrandSince lists are not valid binding forms, would allowing (let [(custom-destructuring-macro x y) data] ...) be a bad idea?
12:37rhickey_lists are being saved for some future extension
12:41cgrandok
12:42vincenzrhickey_: ah I see how it works now
12:43vincenzrhickey_: the vector is a literal, which is then trasnmuted to a pattern
12:44cgrandrhickey, could the else form in if-let be optional?
12:53Chousercgrand: you want when-let
12:59cgrandchouser: 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:00cgrandTo sum up: if/when and if-let/when-let are not "symmetric" and that annoy me
13:00cgrandannoys
13:05Chouserah
13:06Chouserjust use cond for everything. ;-)
13:08Chouseroh, I see. 'if' allows you to skip the else, but 'if-let' doesn't. Yeah, that doesn't seem right.
13:25rhickey_cgrand: I will look at that
13:25cgrandthanks
19:24drewrHow do I extract a class constant?
19:24drewr(. Collection EMPTY_LIST)
19:25drewr--> CompilerException
19:25drewrProbably because the reader can't figure out what EMPTY_LIST is.
20:28Chouserdrewr: (. java.util.Collections EMPTY_LIST)
22:59blbrownhello
23:00drewrblbrown: Hi.
23:03blbrowndrewr: http://groups.google.com/group/clojure/browse_thread/thread/ca468c3548b7d16d do you know anything about this.
23:07drewrHm.
23:08drewrI would point you to Rich's ant.clj. It uses a JFrame.
23:09blbrownthis might help, I am looking at this example: http://clojure.sourceforge.net/features/jvm_hosted.html
23:10drewrYeah, I've played around with that.
23:20blbrownhmm, his example does the same thing....if you run with 'clj theexample.clj'
23:21drewrLet me know what you figure out.
23:22blbrownit is probably bad practice, but I guess I will just add a loop; maybe I am supposed place with the agents or something