On Mon, Aug 3, 2009 at 3:45 PM, Richard Newman <holyg...@gmail.com> wrote:
> > > user=> (macroexpand-1 '(memfn add x y)) > > (clojure.core/fn [target__4193__auto__ x y] (. target__4193__auto__ > > (add x y))) > > > > That is, basically (fn [object x y] (.add object x y)). > > .add is macroexpanded into the more general dot form, as shown in the > memfn expansion. > > user=> (read-string "(.foo bar)") > (.foo bar) > user=> (macroexpand-1 *1) > (. bar foo) So, it treats ".foo" in form-initial position as a macro, though not elsewhere (so "(doc .foo)" does not produce "Macro." and other data). Plain "." is reported as a "Special Form" by doc. It is definitely interesting sometimes to poke at the guts of Clojure in the REPL. :) One apparent deficiency brought to light by all of this: since "memfn" is a macro, it's not itself composable. Other macros where I've found this to occasionally be a problem are "and" and "or" (where I wanted to do something like (reduce and (map pred? coll))) but it's easy enough to make function versions of all of them: (defn and-ns "A non-short-circuiting \"and\" usable in reduce etc." ([] true) ([a] a) ([a b] (and a b)) ([a b & more] (reduce and-ns (and a b) more))) (defn or-ns "A non-short-circuiting \"or\" usable in reduce etc." ([] false) ([a] a) ([a b] (or a b)) ([a b & more] (reduce or-ns (or a b) more))) (defn make-memfn "Given a quoted method name and a quoted vector of argument names, returns a function that can be composed and that takes a target object plus the named arguments and invokes the named method on that target with those arguments." [name arg-vec] (eval `(fn [target# ~...@arg-vec] (. target# (~name ~...@arg-vec))))) Of course, the first two don't short-circuit like their macro counterparts, and the latter needs its arguments quoted. The latter generates: user=> (make-memfn 'add '[x y]) (clojure.core/fn [target__15__auto__ x y] (. target__15__auto__ (add x y))) (obtained by dropping the eval from make-memfn, so it just returned the backquoted expression; compare with memfn above). Of course you're probably doing some serious voodoo if you are generating memfns on the fly from run-time-determined names and argument vectors. Metaprogramming, or making some kind of Java-object inspector, or whatever. The function versions of and and or are much more generally useful, since reductions over maps of predicates arise from time to time in more ordinary situations. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---