2008-05-14
| 08: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? |
| 09:31 | asbjxrn | Is there a way to turn 'foo/bar into 'bar ? |
| 09:33 | asbjxrn | or alternatively: Is there a way to do ({'foo 1 'bar 2} 'gaz/bar) to return 2 and not nil? |
| 09:35 | cgrand | asbjxrn: (symbol (name 'foo/bar)) |
| 09:36 | asbjxrn | Works. |
| 09:40 | asbjxrn | How about: Is it possible to make this return just bar :(do (defmacro foo [] `'bar) (foo)) |
| 09:44 | asbjxrn | (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:45 | cgrand | and using keywords instead of symbols? |
| 09:46 | asbjxrn | I'd prefer not to. |
| 09:47 | asbjxrn | 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. |
| 09:49 | cgrand | If you persiste with symbols: (defmacro foo [] ''bar) ({'bar 2} (foo)) |
| 09:49 | cgrand | -> 2 |
| 09: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 ' |
| 09:50 | rhickey | {`foo 1 `bar 2} |
| 09:50 | rhickey | that way your foo and bar are different from mine |
| 09:51 | rhickey | and a key advantage over keywords |
| 09:51 | rhickey | cgrand: looking at Writer now so I can look at what you are talking about |
| 09:55 | rhickey | cgrand: so the issue is that providing a version of write overrides all super versions? |
| 09: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. |
| 09:56 | cgrand | rhickey: yes and I have to check the types of the arguments to know which write was called |
| 09:57 | rhickey | a type-case macro would make the type-switch easier |
| 09:57 | cgrand | I have a patch that allow me to write :methods [['append [java.lang.CharSequence] java.io.Writer :as 'append-cs]] |
| 09:58 | rhickey | append(char) still goes to super? |
| 09:58 | cgrand | yes |
| 09: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 | rhickey | 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 | rhickey | 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 | rhickey | some convention for array names |
| 10:13 | rhickey | <> |
| 10:13 | rhickey | write-char<> |
| 10:15 | cgrand | I was thinking of prepending method descriptors (but it would require some escaping) |
| 10:16 | cgrand | I meant appending... |
| 10:28 | cgrand | 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 | rhickey | 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 | rhickey | 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 | cgrand | (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 | asbjxrn | (say instead of background, I have a function (circle radius x y) |
| 11:34 | asbjxrn | 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 | asbjxrn | (kinda convoluted explanation...) |
| 11:35 | asbjxrn | (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 | rhickey | 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 | asbjxrn | Is there a (number? x) function? |
| 11:51 | rhickey | (instance? Number x) |
| 11:55 | rhickey | (defn mk-bk [key] |
| 11:55 | rhickey | (fn [env] |
| 11:55 | rhickey | (let [g (env :graphics) |
| 11:55 | rhickey | x (lookup key env)] |
| 11:55 | rhickey | (. g (setColor (new Color x x x))) |
| 11:55 | rhickey | (. g (fillRect 0 0 (lookup `width env) (lookup `height env))) |
| 11:55 | rhickey | env))) |
| 11:55 | rhickey | (defmacro background [x] |
| 11:55 | rhickey | `(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 | asbjxrn | '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 | rhickey | (that should be easier) |
| 12:22 | asbjxrn | resolve in this case means? |
| 12:22 | asbjxrn | (cl:intern ? |
| 12:25 | asbjxrn | 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 | asbjxrn | I meant what I said when I said lot of time to pound... ^xv means what? |
| 12:41 | asbjxrn | 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 | asbjxrn | 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 | rhickey | 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 | rhickey | parallel min/max/reduce/filter/map etc |
| 17:43 | rhickey | also added lazily persistent vectors |
| 17:45 | rhickey | parallel reduce 3x faster on my quad core |
| 19:42 | rhickey | I've added docs to parallel.clj |