#clojure logs

2008-05-14

08:26cgrandrhickey: 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?
09:31asbjxrnIs there a way to turn 'foo/bar into 'bar ?
09:33asbjxrnor alternatively: Is there a way to do ({'foo 1 'bar 2} 'gaz/bar) to return 2 and not nil?
09:35cgrandasbjxrn: (symbol (name 'foo/bar))
09:36asbjxrnWorks.
09:40asbjxrnHow about: Is it possible to make this return just bar :(do (defmacro foo [] `'bar) (foo))
09:44asbjxrn(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.
09:45cgrandand using keywords instead of symbols?
09:46asbjxrnI'd prefer not to.
09:47asbjxrnHmm. 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.
09:49cgrandIf you persiste with symbols: (defmacro foo [] ''bar) ({'bar 2} (foo))
09:49cgrand-> 2
09:49rhickeyasbjxrn: 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 '
09:50rhickey{`foo 1 `bar 2}
09:50rhickeythat way your foo and bar are different from mine
09:51rhickeyand a key advantage over keywords
09:51rhickeycgrand: looking at Writer now so I can look at what you are talking about
09:55rhickeycgrand: so the issue is that providing a version of write overrides all super versions?
09:55asbjxrnOk. {`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.
09:56cgrandrhickey: yes and I have to check the types of the arguments to know which write was called
09:57rhickeya type-case macro would make the type-switch easier
09:57cgrandI have a patch that allow me to write :methods [['append [java.lang.CharSequence] java.io.Writer :as 'append-cs]]
09:58rhickeyappend(char) still goes to super?
09:58cgrandyes
09:58rhickeyhmm...
10:00asbjxrnThis 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:00rhickeyone of the design objectives was to minimize the number of cases where an implementation change would require a re-gen
10:02rhickeycgrand: so if you later wanted to implement append(char) similarly, you would need another :methods entry
10:05cgrandyes -- and it would clash with the previous def if I'm using gen-and-load-class
10:05rhickeyright re-gen means re-load means re-start :(
10:07rhickeyso 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:07cgrandhmm...
10:12rhickeyappend-char, append-CharSequence, append-CharSequence-int-int
10:13rhickeysome convention for array names
10:13rhickey<>
10:13rhickeywrite-char<>
10:15cgrandI was thinking of prepending method descriptors (but it would require some escaping)
10:16cgrandI meant appending...
10:28cgrandI 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:28rhickeysometimes it's convenient to route the overloads to a single function
10:32rhickeythe 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:36cgrandI 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:40rhickeyOh, 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:41rhickeyI wouldn't let perf considerations dominate here - the perf will be good, the lookups aren't really lookups, just binding tests
11:21asbjxrnThis 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:21lisppaste8asbjxrn pasted "evaluation of symbols in macros" at http://paste.lisp.org/display/60762
11:21asbjxrnKind of a writeup here:
11:26cgrandasbjxrn: try putting a quote before ~x : (lookup '~x env#) I think it will prevent resolution of your symbol after macroexpansion
11:27cgrand(foerget it: I read too quickly)
11:29rhickeyone 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:30asbjxrnNot just quoting, I don't want the "width" to be evaluated until the function that the macro creates is called later.
11:31rhickeyyou can write a function that returns a function
11:31asbjxrnBut when calling that function-creating function, the arguments will be evaluated, right?
11:32asbjxrn(say instead of background, I have a function (circle radius x y)
11:34asbjxrnAnd 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:34asbjxrn(kinda convoluted explanation...)
11:35asbjxrn(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:42rhickeyright 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:43rhickeymake-bk-fn
11:47asbjxrnOk. But that still leaves me confused as to how to embed the symbol. (I'll try to distill the problem a bit.)
11:50asbjxrnIs there a (number? x) function?
11:51rhickey(instance? Number x)
11:55rhickey(defn mk-bk [key]
11:55rhickey (fn [env]
11:55rhickey (let [g (env :graphics)
11:55rhickey x (lookup key env)]
11:55rhickey (. g (setColor (new Color x x x)))
11:55rhickey (. g (fillRect 0 0 (lookup `width env) (lookup `height env)))
11:55rhickey env)))
11:55rhickey(defmacro background [x]
11:55rhickey `(mk-bk 'x))
11:57lisppaste8rhickey annotated #60762 with "macro rev" at http://paste.lisp.org/display/60762#1
12:01asbjxrnUhm.
12:02asbjxrn'x should be ~x?
12:03rhickeyoops '~x
12:15asbjxrnOk, 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:15jteoyay for you. :)
12:18lisppaste8asbjxrn annotated #60762 with "some final work on lookup" at http://paste.lisp.org/display/60762#2
12:18asbjxrnIn case anyone cares.
12:21lisppaste8rhickey annotated #60762 with "capturing resolved symbol" at http://paste.lisp.org/display/60762#3
12:22rhickeyif you wanted to resolve the symbol at point of macro call
12:22rhickey(that should be easier)
12:22asbjxrnresolve in this case means?
12:22asbjxrn(cl:intern ?
12:25asbjxrnOk, it basically expands 'foo -> bar/foo iff foo is a defined symbol in the namespace bar.
12:26rhickeyif 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:28asbjxrnYea, I misread the result of my command, it doesn't return the symbol 'bar/foo, but eg. #<Var: bar/foo>
12:35asbjxrnI meant what I said when I said lot of time to pound... ^xv means what?
12:41asbjxrnNot 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:43asbjxrnAnyway, it's getting late and my head is spinning. Thanks for all the help.
12:55rhickeyI meant, that should be easier than it is, not easier for what you are doing
17:41rhickeyIf 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:42rhickeyparallel min/max/reduce/filter/map etc
17:43rhickeyalso added lazily persistent vectors
17:45rhickeyparallel reduce 3x faster on my quad core
19:42rhickeyI've added docs to parallel.clj