Clojure - Writing Macros
Writring Macros
Macro structure
Macros are structured the same way as functions, they have a docstring, arguments and body. We can also use argument destructuring and can create multiple arity macros.
1(defmacro infix
2 "Use infix syntax for calling functions"
3 [[operand1 op operand2]]
4 (list op operand1 operand2))
Building Macros
Distinguishing Symbols and Values
Macro body always tries to get the value of the symbol. We sometimes want to return the symbol
itself without getting its value. To turn off this evaluation Clojure uses a single quote character
'.
1(defmacro my-print-error
2 "Prints and returns a result of expression but errors"
3 [expression]
4 (list let [result expression]
5 (list println result)
6 (result)))
7
8(defmacro my-print
9 [expression]
10 (list 'let ['result expression]
11 (list 'println 'result)
12 ('result)))
In this example we use quoting to stop Clojure from evaluating let and println. We also use
it to bind result so we can get its value.
Syntax Quoting
Syntax quoting is similar to regular quoting in that it returns unevaluated data structures, but they differ in that syntax quoting will return fully qualified symbols (symbols with the symbol’s namespace included).
1'+
2; => +
3
4`
5; => clojure.core/+
Another difference is that syntax quoting allows us to unqoute forms using tilde ~.
1`(+ 1 ~(inc 1))
2; => (clojure.core/+ 1 2)
3
4`(+ 1 (inc 1))
5; => (clojure.core/+ 1 (clojure.core/inc 1))
Syntax quoting leads to more readable and concise code.