(defmacro macro-name [& args]
...)
Quoting prevents the form following the single-quote sign from being evaluated:
user=> (def my-list '(1 2 3))
Like quote in that it prevents the evaluation of the form following its operator (`). The difference is that it attempts to namespace-qualify all symbols in the given form:
user=> `(+ my-list)
;; (clojure.core/+ user/my-list)
In a quoted form, unquote (~) forces the evaluation of the form following it at macro-expansion time:
user=> `(+ ~my-list)
;;(clojure.core/+ (1 2 3))
In a quoted form, unquote-splicing (~@) forces the evaluation of the form - which is assumed to be a list - and unpacks its content in the position it is used:
user=> `(+ ~@my-list)
;; (clojure.core/+ 1 2 3)
The built-in macroexpand
function expands the given quoted form until it doesn't represent a macro any longer:
user=> (macroexpand '(cond
(even? 2) "even"
:else "odd"))
;; (if (even? 2)
;; "even"
;; (clojure.core/cond :else "odd"))
Sometimes it's useful to recursively expand macros until the form can't be expanded further. The function macroexpand-all
from the clojure.walk
namespace does just that:
user=> (require '[clojure.walk :as w])
user=> (w/macroexpand-all '(cond
(even? 2) "even"
:else "odd"))
;; (if (even? 2)
;; "even"
;; (if :else "odd" nil))