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
-~----------~----~----~----~------~----~------~--~---

Reply via email to