Macros
The language has support for Lisp-style macros. Macros are like preprocessor directives and allow the manipulation of the language syntax before evaluation.
There are two built-in macros: defn
which is a shortcut for the form (def ... (fn ...))
and defmacro
which is a shortcut for the form (def ... (macro ...))
. To illustrate how macros work, lets look at the definition of defn
:
(def defn (macro (name args body) (quasiquote (def (unquote name) (fn (unquote args) (unquote body))))))
We can use the special form macroexpand
to test macro expansion without evaluating the resulting code:
> (macroexpand (defn add (a b) (+ a b)))
(def add (fn (a b) (+ a b)))
The quasiquote
form is essential for declaring macros. Internally macros are just functions with a special flag.
Examples
Lets combine if
and not
into a macro named unless
, this time using a shorter syntax:
> (defmacro unless (pred a b) `(if (not ~pred) ~a ~b))
<macro>
> (unless (< 2 1) "false" "true")
"false"
> (macroexpand (unless (< 2 1) "false" "true"))
(if (not (< 2 1)) "false" "true")
For another example, we can use the lambda symbol to replace fn
:
(defmacro λ (args body) (quasiquote (fn (unquote args) (unquote body))))
<macro>
> (λ (a) (+ a 1))
<function>
> (macroexpand (λ (a) (+ a 1)))
(fn (a) (+ a 1))