= Macros
Rich Hickey
2015-01-01
:type: reference
:toc: macro
:icons: font
:prevpagehref: special_forms
:prevpagetitle: Special Forms
:nextpagehref: other_functions
:nextpagetitle: Other Functions

ifdef::env-github,env-browser[:outfilesuffix: .adoc]

toc::[]

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.

Some macros produce simple combinations of primitive forms. For example, https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when[`when`] combines <<special_forms#if,`if`>> and <<special_forms#do,`do`>>:

[source,clojure-repl]
----
user=> (macroexpand '(when (pos? a) (println "positive") (/ b a)))
(if (pos? a) (do (println "positive") (/ b a)))
----

Other macros re-arrange forms in useful ways, like the `pass:[->]` macro, which recursively inserts each expression as the first argument of the next expression:

[source,clojure-repl]
----
user=> (-> {} (assoc :a 1) (assoc :b 2))
{:b 2, :a 1}
user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2)))
(assoc (assoc {} :a 1) :b 2)
----

== Special variables

Two special variables are available inside defmacro for more advanced usages:

* `&form` - the actual form (as data) that is being invoked
* `&env` - a map of local bindings at the point of macro expansion. The env map is from symbols to objects holding compiler information about that binding.

All of the following macros are documented on the https://clojure.github.io/clojure/[API] page. Many are also discussed on topic pages as noted:

[%hardbreaks]
Creating macros: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmacro[defmacro] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/definline[definline] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/macroexpand-1[macroexpand-1] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/macroexpand[macroexpand]
Branching: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/and[and] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/or[or] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when[when] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-not[when-not] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-let[when-let] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-first[when-first] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/if-not[if-not] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/if-let[if-let] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/cond[cond] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/condp[condp]
Looping (see also <<sequences#,Sequences>>): https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for[for] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doseq[doseq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dotimes[dotimes] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/while[while]
Working with vars (see also <<vars#,Vars and Environment>>): https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/declare[declare] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmacro[defmacro] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/definline[definline] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmethod[defmethod] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmulti[defmulti] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn-[defn-] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defonce[defonce] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defstruct[defstruct]
Arranging code differently: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/%2E%2E[..] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doto[doto] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-%3e[pass:[->]]
Dynamic scopes (see also <<vars#,Vars and Environment>>): https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/binding[binding] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/locking[locking] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/time[time] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-in-str[with-in-str] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-local-vars[with-local-vars] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-open[with-open] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-out-str[with-out-str] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-precision[with-precision]
Creating lazy things (see also <<sequences#,Sequences>>): https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-seq[lazy-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-cat[lazy-cat] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/delay[delay]
<<java_interop#,Java interop>> macros: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/%2E%2E[..] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/amap[amap] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/areduce[areduce] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class[gen-class] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-interface[gen-interface] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy[proxy] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy-super[proxy-super] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/memfn[memfn]
Documenting code: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/assert[assert] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/comment[comment] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doc[doc]
Transactions: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dosync[dosync] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/io![io!]

A few <<special_forms#,special forms>> are actually implemented as macros, primarily to provide destructuring: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/fn[fn] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/let[let] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/loop[loop]
