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:
defmacro
is a special form you use to define a macro.infix
is 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 list
with the values of the parameters provided to the infix
macro 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
The 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
operator:
(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.