Macros

Clojure has a programmatic macro system which allows the compiler to be extended by user code. Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. Many core constructs of Clojure are not, in fact, primitives, but are normal macros. First we'll cover some of the included macros and then look at the facilities for creating your own.


(and exprs*)

Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true.


(or exprs*)

Evaluates exprs one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil.


(when test exprs*)

Evaluates test. If logical true, evaluates exprs in an implicit do.


(when-not test exprs*)

Evaluates test. If logical false, evaluates exprs in an implicit do.


(cond test-expr-pairs*)

test-expr-pair => test expr

cond takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil. cond is a succinct and readable alternative to nested ifs.


(locking x exprs*)

Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances.


(defn name [params* ] exprs*)

(defn name ([params* ] exprs*)+)

Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+))


(defmacro name [params* ] exprs*)

(defmacro name ([params* ] exprs*)+)

Like defn, but the resulting function name is declared as a macro and will be used as a macro by the compiler when it is called.


(macroexpand-1 form)

Function. If form represents a macro form, returns its expansion, else returns form.

(macroexpand-1 '(defn foo [x] x))
-> (def foo (fn [x] x))

(macroexpand form)

Function. Repeatedly calls macroexpand-1 on form until it no longer represents a macro form, then returns it. Note neither macroexpand-1 nor macroexpand expand macros in subforms.


(-> expr forms+)

Threads the expr through the forms. Inserts expr as the second item in the first form. If there are more forms, inserts the first form as the second item in second form, etc.

(-> {} (assoc :a 1) (assoc :b 2))
-> {:a 1, :b 2}
(macroexpand '(-> {} (assoc :a 1) (assoc :b 2)))
-> (assoc (clojure/-> {} (assoc :a 1)) :b 2)

Copyright © Rich Hickey