2008-04-24
| 00:13 | beau | hey guys |
| 00:14 | beau | just wanted to say that I've recently discovered Clojure and find it exciting |
| 00:14 | beau | I like the idea of combining my depth in Java with my passion for lisp |
| 00:15 | beau | thanks for all the hard work rhickey |
| 06:52 | leafw | hi all |
| 06:52 | leafw | I am trying to build an command line interface for clojure |
| 06:52 | leafw | I tried to emulate the Repl.java |
| 06:53 | leafw | using PipedReader and PipedWriter to pass text directly to the LispReader |
| 06:53 | leafw | but the latter just blocks |
| 06:53 | leafw | essentially I am looking for the equivalent of PythonInterpreter.exec( String code ) |
| 06:54 | leafw | but there is only a Compiler.eval(Object ..) which I think expects tokens |
| 08: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 | rhickey_ | (let [{\: [a b c]} {:a 1 :b 2 :c 3}] [a b c]) |
| 10:49 | rhickey_ | (let [{\" [a b c]} {"a" 1 "b" 2 "c" 3}] [a b c]) |
| 10:49 | rhickey_ | (let [{\' [a b c]} '{a 1 b 2 c 3}] [a b c]) |
| 10:56 | rhickey_ | i.e. (let [{:keys [a], :strs [b], :syms [c]} {:a 1 "b" 2 'c 3}] [a b c]) becomes: |
| 10:56 | rhickey_ | (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 | Chouser | 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 | rhickey_ | 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 | Chouser | := in particular seems like a nice complement for cases were you don't mind not having the literal symbol. |
| 10:59 | Chouser | I don't mind the \: puncutation, that at first glance [{\' looks a little scarey. |
| 11:00 | Chouser | "though at first" |
| 11:02 | Chouser | 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 | rhickey_ | (let [{\: [a], \" [b], \' [c]} {:a 1 "b" 2 'c 3}] [a b c]) |
| 11:04 | rhickey_ | (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 | rhickey_ | (let [{\: [a b c]} {:a 1 :b 2 :c 3}] [a b c]) |
| 11:06 | rhickey_ | (let [{:= [:a :b :c]} {:a 1 :b 2 :c 3}] [a b c]) |
| 11:07 | Chouser | do you dislike having \: \" \' as well as := ? |
| 11:08 | Chouser | having the literal symbols visible is probably more important to me than a few extra keystrokes here or there. |
| 11:08 | Chouser | 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 | Chouser | My editor's search function and syntax highlighter can help me find the former, but (currently) fails for the latter. |
| 11:12 | Chouser | I assume that would be try of most editors. |
| 11:12 | Chouser | 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 | rhickey_ | (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 | rhickey_ | (let [{\: [a b c]} amap] [a b c]) |
| 11:14 | rhickey_ | (let [{:= [:a :b :c]} amap] [a b c]) |
| 11:15 | rhickey_ | (others please chime in :) |
| 11:17 | rhickey_ | or strings: |
| 11:17 | rhickey_ | (let [{\" [a b c]} amap] [a b c]) |
| 11:17 | rhickey_ | (let [{:= ["a" "b" "c"]} amap] [a b c]) |
| 11:19 | Chouser | might get more input on the google group |
| 11:19 | rhickey_ | \= or \' for symbols: |
| 11:20 | rhickey_ | (let [{\= [a b c]} amap] [a b c]) |
| 11:20 | rhickey_ | (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 | Chouser | less perlish? |
| 11:22 | jteo | yup |
| 11:26 | rhickey_ | head-to0 |
| 11:26 | rhickey_ | head-to-head: |
| 11:26 | rhickey_ | (let [{:keys [a b c]} amap] [a b c]) |
| 11:26 | rhickey_ | (let [{\: [a b c]} amap] [a b c]) |
| 11:26 | rhickey_ | (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 | Chouser | \: 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 | rhickey_ | (let [{:= ["a" "b" "c"]} amap] [a b c]) |
| 11:38 | rhickey_ | 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 | vincenz | why not simply |
| 11:44 | vincenz | {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 | vincenz | cgrand: the latter is false |
| 11:47 | vincenz | cgrand: this is a binding not an expression |
| 11:47 | vincenz | different syntactical {} |
| 11:48 | cgrand | ah? |
| 11:48 | vincenz | (let [binding exp] exp) |
| 11:49 | vincenz | but yes, you mke a good point about different keytypes :) |
| 11:49 | vincenz | (let ({:a => a, "foo" => b, 1 => c} amap) [a b c]) |
| 11:51 | vincenz | 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 | vincenz | ? |
| 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 | vincenz | rhickey_: how does this not nest? |
| 11:52 | vincenz | (let ({:a {:b a} "foo" b 1 c} amap) [a b c]) |
| 11:53 | vincenz | {key pat ..} |
| 11:53 | rhickey_ | that is the current destructuring support already |
| 11:53 | vincenz | oh |
| 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 | vincenz | (let ((some-macro-name a b c) amap) [a b c]) |
| 11:55 | vincenz | 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 | rhickey_ | 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 | vincenz | rhickey_: the vector is a literal, which is then trasnmuted to a pattern |
| 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 | cgrand | To sum up: if/when and if-let/when-let are not "symmetric" and that annoy me |
| 13:00 | cgrand | annoys |
| 13:05 | Chouser | ah |
| 13:06 | Chouser | just use cond for everything. ;-) |
| 13:08 | Chouser | 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 | drewr | (. Collection EMPTY_LIST) |
| 19:25 | drewr | --> CompilerException |
| 19:25 | drewr | 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 | drewr | 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 |