Cover by Brian Carper, Christophe Grand, Chas Emerick

Safari, the world’s most comprehensive technology and business learning platform.

Find the exact information you need to solve a problem on the fly, or go deeper to master the technologies and skills you need to succeed

Start Free Trial

No credit card required

O'Reilly logo

Syntax

Since macros return Clojure data structures, we will often want to return lists to represent further calls, either of functions, special forms, or other macros. Therefore, we need tools to build these lists. It’s perfectly acceptable to use the simplest tool in our toolbox, the list function:

(defmacro hello
  [name]
  (list 'println name))

(macroexpand '(hello "Brian"))
;= (println "Brian")

However, for more complex macros that return something more than a simple flat list, this quickly becomes unwieldy. This is how the source code for the standard macro while would look, written in this manner:

(defmacro while
  [test & body]
  (list 'loop []
    (concat (list 'when test) body)
      '(recur)))

The gist of this macro is lost in all the calls to list and concat.

Therefore, Clojure offers some syntactic sugar for working with lists and interpolating named values into them. Using this sugar, the while macro[169] is much more readable:

(defmacro while
  [test & body]
  `(loop []
     (when ~test
       ~@body
       (recur))))

This macro uses three tools: syntax-quote,[170] unquote, and splicing-unquote. This syntax is not intrinsic to macros. You can use it in functions or other code as well, but because macros deal so heavily with lists, macros are the place you’ll use these the most.[171]

quote Versus syntax-quote

You should be familiar with the quote special form already, which returns its arguments unevaluated. As a shortcut, we can write (quote (a b)) as '(a b), both of which evaluate to a list with two elements, the ...

Find the exact information you need to solve a problem on the fly, or go deeper to master the technologies and skills you need to succeed

Start Free Trial

No credit card required