Clojure uses prefix notation, that is: The operator comes before its operands.
For example, a simple sum of two numbers would be:
(+ 1 2) ;; => 3
Macros allow you to manipulate the Clojure language to a certain degree. For example, you could implement a macro that let you write code in infix notation (e.g.,
1 + 2):
(defmacro infix [first-operand operator second-operand] "Converts an infix expression into a prefix expression" (list operator first-operand second-operand))
Let’s break down what the code above does:
defmacrois a special form you use to define a macro.
infixis the name of the macro we are defining.
[first-operand operator second-operand]are the parameters this macro expects to receive when it is called.
(list operator first-operand second-operand)is the body of our macro. It simply creates a
listwith the values of the parameters provided to the
infixmacro and returns that.
defmacro is a special form because it behaves a little differently compared to other Clojure constructs: Its parameters are not immediately evaluated (when we call the macro). This is what allows us to write something like:
(infix 1 + 2) ;; => 3
infix macro will expand the
1 + 2 arguments into
(+ 1 2), which is a valid Clojure form that can be evaluated.
If you want to see what the
infix macro generates, you can use the
(macroexpand '(infix 1 + 2)) ;; => (+ 1 2)
macroexpand, as implied by its name, will expand the macro (in this case, it will use the
infix macro to transform
1 + 2 into
(+ 1 2)) but won’t allow the result of the macro expansion to be evaluated by Clojure’s interpreter.