liveBook · Manning

Macro expansion

As explained in Clojure: The Essential Reference

Macro expansion is the compile-time transformation of a macro invocation into the expression that will be evaluated.

Macro expansion transforms a macro invocation into the expression that will be evaluated, without evaluating the resulting form. Use it at the REPL to inspect behavior, understand generated code, or debug macros. section 4.2

Choose the expansion function according to the depth you need:

  • macroexpand-1 expands only the outermost form once. section 4.2
  • macroexpand repeatedly expands the outermost form until it is no longer a macro, without entering inner forms. section 4.2
  • clojure.walk/macroexpand-all expands outer forms and macro invocations nested inside them. section 4.2

Compare expansion depth

(macroexpand-1 '(when-first [a [1 2 3]] (println a))) ;; expands the outer when-first once (macroexpand '(when-first [a [1 2 3]] (println a))) ;; continues expanding the outer generated forms (clojure.walk/macroexpand-all '(when-first [a [1 2 3]] (println a))) ;; also expands nested when, let, and related forms The input must be a valid Clojure expression; each function returns a form rather than evaluating it. section 4.2

Inspect short-circuiting

(clojure.walk/macroexpand-all '(and false true true)) ;; reveals nested let* and if forms Expansion makes the control flow behind macros such as and visible, including their short-circuit behavior. section 3.2.2

Listing 4.2. → Macro inspection, REPL util, Debugging
(macroexpand form)

(macroexpand-1 form)

(clojure.walk/macroexpand-all form)

Browse the compact REPL reference for the three macro inspection functions. section 4.2

How Clojure: The Essential Reference covers it

How deep it goes
Explains one-step, repeated outer, and recursive expansion, stopping short of evaluating or fully analyzing generated code.
Examples
Uses when-first and and forms to compare expansion depth and expose short-circuit implementation.
What it assumes
Assumes valid Clojure expressions and macro invocations while clarifying the expansion functions’ input and output contract.
What you can do after
Diagnose macro behavior by inspecting returned forms and compare expansion depth with named Clojure functions.
How it connects
Connects macros with Clojure expressions, the REPL, debugging, clojure.walk, and code analysis.

Also explained in

Compare how 4 books explain macro expansion →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.