I've been going through Stuart Halloway's book, _Programming Clojure_, and thinking about his deftarget macro has brought up some questions as to how macros and special forms interact in clojure. The deftarget macro needs to produce a "def" form that has metadata on its first argument, which is a symbol. Typically this is done with a reader macro, e.g. (def #^{:foo "bar"} x ...), but reader macros are problematic inside of (regular) macros, as they are executed before macro expansion. Stuart's solution involves doing some gensyms, but I thought it would be nice to just have a form of def what was more macro friendly. So I defined
(defmacro def-with-md [md sym & optional-init] `(def ~(with-meta sym md) ~...@optional-init)) which means I can now write things like (defmacro foo [...] `(let [a# (...)] (def-with-md {:a a#} x (...)))) This got me thinking about whether I could attack the problem even more directly. I defined another macro: (defmacro wmd [s md] (with-meta s md)) Trying it out: (macroexpand '(wmd x {:a 1})) ==> x But (def (wmd x {:a 1}) 37) gives me an error: "Second argument to def must be a Symbol". This confuses me. Doesn't macro expansion happen entirely before evaluation? So before the def special form is evaluated, (wmd x {:a 1}) should have already been macro expanded to give a symbol. (And why is it talking about the *second* argument, instead of the *first*?) --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---