In other words, is there any way to trigger macro expansion on forms that don't look like (MACRO arg* ...)
.
To give a hypothetical example:
(defmacro my-var
(do (printf "Using my-var!\n") 42))
(+ my-var 1) ;; Should print & return 43
What I really want to do is call macroexpand
on a term with free variables. I want to these free variables should have special meaning during macro expansion, but should go back to "normal" afterward.
This facility currently exists in Clojure as one of the features of the Clojure Contrib library tools.macro. The relevant tools.macro macros are defsymbolmacro
, with-symbol-macros
and symbol-macrolet
– here's a symbol-macrolet
example from the README (as found on the tip of the master branch right now):
(symbol-macrolet [def foo]
(def def def))
expands to (def def foo)
symbol-macrolet
is used to introduce lexically scoped symbol macros, while defsymbolmacro
introduces symbol macros to be applied inside any with-symbol-macros
blocks (doing away with with-symbol-macros
would only be possible with support from the Clojure compiler itself).
AFAIK, some version of symbol-macrolet
has been a planned feature for inclusion in Clojure's compiler itself for quite a while; it is expected that when and if it lands, it will likely be called letmacro
. There's no concrete public timeline for that, though, and it is certainly not guaranteed to land at all.
The names that tools.macro uses are inspired by Common Lisp, where the relevant macros are known as define-symbol-macro
and symbol-macrolet
. Since this is a standard compiler feature in CL, symbol macros introduced with define-symbol-macro
are actually applied globally without assistance from any helper macros.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With