Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does clojure have identifier macros?

Tags:

macros

clojure

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.

like image 546
Ben Greenman Avatar asked Dec 24 '22 12:12

Ben Greenman


1 Answers

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.

like image 180
Michał Marczyk Avatar answered Jan 05 '23 21:01

Michał Marczyk