#clojure log - May 14 2008

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

8:26 cgrand: rhickey: I used gen-class to extend java.io.Writer but overloaded methods make this not so fun (too much type tests and var-bindings to access super's for some arities). Would you be ok with a way to bind a method signature to a different var?

9:31 asbjxrn: Is there a way to turn 'foo/bar into 'bar ?

9:33 or alternatively: Is there a way to do ({'foo 1 'bar 2} 'gaz/bar) to return 2 and not nil?

9:35 cgrand: asbjxrn: (symbol (name 'foo/bar))

9:36 asbjxrn: Works.

9:40 How about: Is it possible to make this return just bar :(do (defmacro foo [] `'bar) (foo))

9:44 (This thing is happening at rather high frequencies, better to create the symbol without the namespace instead of removing it later by going by the string if possible.

9:45 cgrand: and using keywords instead of symbols?

9:46 asbjxrn: I'd prefer not to.

9:47 Hmm. On the other hand... It's kind of a parser thingy, and translation to keywork would only happen once. Maybe that is a better option.

9:49 cgrand: If you persiste with symbols: (defmacro foo [] ''bar) ({'bar 2} (foo))

9:49 -> 2

9:49 rhickey: asbjxrn: why wouldn't the symbols get resolved correctly, i.e. one of the points of using symbols is to get the resolution - so use ` instead of '

9:50 {`foo 1 `bar 2}

9:50 that way your foo and bar are different from mine

9:51 and a key advantage over keywords

9:51 cgrand: looking at Writer now so I can look at what you are talking about

9:55 cgrand: so the issue is that providing a version of write overrides all super versions?

9:55 asbjxrn: Ok. {`foo 1 `bar 2} Sounds like a plan. I'm still fiddling with my environment map, which will cointain built-in and user specified variables. greating the built in variables in "my" namespace might be the right thing.

9:56 cgrand: rhickey: yes and I have to check the types of the arguments to know which write was called

9:57 rhickey: a type-case macro would make the type-switch easier

9:57 cgrand: I have a patch that allow me to write :methods [['append [java.lang.CharSequence] java.io.Writer :as 'append-cs]]

9:58 rhickey: append(char) still goes to super?

9:58 cgrand: yes

9:58 rhickey: hmm...

10:00 asbjxrn: This damn thing started out as some helper functions and are quickly turning into a bloody language. (Just because I couldn't manage to integrate processing and clojure.) At least I'm learning, I hope.

10:00 rhickey: one of the design objectives was to minimize the number of cases where an implementation change would require a re-gen

10:02 cgrand: so if you later wanted to implement append(char) similarly, you would need another :methods entry

10:05 cgrand: yes -- and it would clash with the previous def if I'm using gen-and-load-class

10:05 rhickey: right re-gen means re-load means re-start :(

10:07 so I'd prefer a dynamic convention for specialized overrrides - perhaos a two stage process - look up append var, if not found look for append-char or some thing, just for overloaded methods

10:07 cgrand: hmm...

10:12 rhickey: append-char, append-CharSequence, append-CharSequence-int-int

10:13 some convention for array names

10:13 <>

10:13 write-char<>

10:15 cgrand: I was thinking of prepending method descriptors (but it would require some escaping)

10:16 I meant appending...

10:28 I just noticed you proposed to first look for a general handler and if not found for a specific... so as to not slow down the "normal" path, I guess.

10:28 rhickey: sometimes it's convenient to route the overloads to a single function

10:32 the special process would only be done for overloaded methods in the first place, so the normal, non-overloaded path doesn't do a speculative lookup

10:36 cgrand: I agree: in some cases all overloads can be handled by a single function and it's better not to cripple the normal path. I was surprised because I was thinking of doing it the other way: first look for a specific handler else look for a fallback (and by default the specific var could point to the var containing the fallback function) -- but your way is certainly better in the normal overloaded path.

10:40 rhickey: Oh, I see. I'm not sure general before specific is better - it will force there to be a specific for all overloads if there is a specific for any

10:41 I wouldn't let perf considerations dominate here - the perf will be good, the lookups aren't really lookups, just binding tests

11:21 asbjxrn: This stuff is making me feel stupid. The `foo solution presents some other problems. You guys got (a lot of) free time to pound some macro/substitution stuff through my skull?

11:21 lisppaste8: asbjxrn pasted "evaluation of symbols in macros" at http://paste.lisp.org/display/60762

11:21 asbjxrn: Kind of a writeup here:

11:26 cgrand: asbjxrn: try putting a quote before ~x : (lookup '~x env#) I think it will prevent resolution of your symbol after macroexpansion

11:27 (foerget it: I read too quickly)

11:29 rhickey: one trick with macros is to make as little as possible a macro or backquote. If the purpose of making it a macro is just to do quoting for you, then have the macro do just that part, then call a function to do the work

11:30 asbjxrn: Not just quoting, I don't want the "width" to be evaluated until the function that the macro creates is called later.

11:31 rhickey: you can write a function that returns a function

11:31 asbjxrn: But when calling that function-creating function, the arguments will be evaluated, right?

11:32 (say instead of background, I have a function (circle radius x y)

11:34 And I want to call it with (circle 10 mousex mousey) where mousex and mousey are entries in the environment map that are set before the function that circle returns is called...

11:34 (kinda convoluted explanation...)

11:35 (wouldn't circle have to be a macro to avoid mousex and mousey to be evaluated (They do not even exist when the circle function is called.))

11:42 rhickey: right now, background expands into a fn literal, embedding the key x (or trying to). Imagine there was an ordinary function, make-bk-fn, that took an env and a key, and returned a fn of env. background could expand into a call to make-bk.

11:43 make-bk-fn

11:47 asbjxrn: Ok. But that still leaves me confused as to how to embed the symbol. (I'll try to distill the problem a bit.)

11:50 Is there a (number? x) function?

11:51 rhickey: (instance? Number x)

11:55 (defn mk-bk [key]

11:55 (fn [env]

11:55 (let [g (env :graphics)

11:55 x (lookup key env)]

11:55 (. g (setColor (new Color x x x)))

11:55 (. g (fillRect 0 0 (lookup `width env) (lookup `height env)))

11:55 env)))

11:55 (defmacro background [x]

11:55 `(mk-bk 'x))

11:57 lisppaste8: rhickey annotated #60762 with "macro rev" at http://paste.lisp.org/display/60762#1

12:01 asbjxrn: Uhm.

12:02 'x should be ~x?

12:03 rhickey: oops '~x

12:15 asbjxrn: Ok, a little more work and it works pretty much the way I want. Now to understand it and what went wrong in my version so I can make the macro bigger again ;-)

12:15 jteo: yay for you. :)

12:18 lisppaste8: asbjxrn annotated #60762 with "some final work on lookup" at http://paste.lisp.org/display/60762#2

12:18 asbjxrn: In case anyone cares.

12:21 lisppaste8: rhickey annotated #60762 with "capturing resolved symbol" at http://paste.lisp.org/display/60762#3

12:22 rhickey: if you wanted to resolve the symbol at point of macro call

12:22 (that should be easier)

12:22 asbjxrn: resolve in this case means?

12:22 (cl:intern ?

12:25 Ok, it basically expands 'foo -> bar/foo iff foo is a defined symbol in the namespace bar.

12:26 rhickey: if an api exposed the keys as defs, there would be corresponding ns-qualified vars, and consumers could use normal namespace tools to distinguish my/foo from your/foo, should they be combined

12:28 asbjxrn: Yea, I misread the result of my command, it doesn't return the symbol 'bar/foo, but eg. #<Var: bar/foo>

12:35 I meant what I said when I said lot of time to pound... ^xv means what?

12:41 Not sure if it is easier. Would have to add a test to check if x is a number and stuff. Probably easier to deal with in the function.

12:43 Anyway, it's getting late and my head is spinning. Thanks for all the help.

12:55 rhickey: I meant, that should be easier than it is, not easier for what you are doing

17:41 If you are interested in parallel computation, I've added parallel.clj, an interface to the Fork/Join framework. Just put jsr166y.jar in your classpath and off you go!

17:42 parallel min/max/reduce/filter/map etc

17:43 also added lazily persistent vectors

17:45 parallel reduce 3x faster on my quad core

19:42 I've added docs to parallel.clj

Logging service provided by n01se.net