compile/quasiquote
Symbol: compile/quasiquote
Syntax: ``EXPR(reader shorthand) or(quasiquote EXPR)`
Use-case: Quasi-quotation: construct a pair structure at compile time with
selected sub-expressions evaluated at runtime. Inside the body, ,EXPR
(unquote) splices a single evaluated value, and ,@EXPR (unquote-splicing)
flattens a list into the surrounding list.
Reader shorthands:
``EXPR
->(quasiquote EXPR)`,EXPR->(unquote EXPR)(only valid inside a quasiquote body),@EXPR->(unquote-splicing EXPR)(only valid inside a quasiquote body)`HEAD: BODY->(quasiquote (#block: (HEAD) ...)); see Block quasiquote
Behaviour: One argument required. The result is the argument rebuilt as data, with each escape replaced by a runtime value. The walk tracks a nesting level, starting at 0:
Atoms (symbols, keywords, numbers, nil) are themselves. A symbol a macro template wrote loses its hygiene mark;
quasiquote-syntaxkeeps it.(unquote INNER)at level 0 evaluatesINNERat runtime and puts its value in that position.(unquote-splicing INNER)at level 0, in list position, evaluatesINNERat runtime and splices its elements into the surrounding list. The value must be a pair or nil. A splice in dotted-tail position is a compile-time error. A splice before a dotted tail ends the spliced list in that tail:`(a ,@xs . b)withxsbound to(1 2)gives(a 1 2 . b), and(a . b)whenxsis empty.(unquote INNER)and(unquote-splicing INNER)at level > 0 are data, not escapes: the form is rebuilt withINNERwalked at level - 1.(quasiquote INNER)at any level is rebuilt as data withINNERwalked at level + 1.Proper lists are rebuilt element by element; dotted pairs keep their tail. Positions that hold no escape are built as constants.
Nesting: Each additional ``` increments the level; each , decrements it.
Dotted tails with unquote: (a . ,x) reads as the three-element proper
list (a unquote x), because (a . (unquote x)) is a proper list. The
compiler treats that trailing unquote as a dotted tail and evaluates it, so
(a . ,(car xs))` with `xs` bound to `(1 2)` gives `(a . 1)`. An atomic tail also produces an improper pair, as in (a . 42) or ``(a . b).
Examples:
;; Atom: just a constant
`42 ; -> 42
`foo ; -> symbol foo
;; Proper list
`(a b c) ; -> (a b c)
;; Unquote -- x is evaluated at runtime
`(a ,x b) ; -> (a <value of x> b)
;; Unquote-splicing -- items is spliced in
`(a ,@items b) ; -> (a item0 item1 ... b)
;; Dotted pair with atom tail
`(a . 42) ; -> (a . 42)
;; Nested quasiquote -- inner unquote is NOT evaluated at outer level
``(a ,(+ 1 2)) ; -> (quasiquote (a (unquote (+ 1 2))))
See also: quasiquote-syntax,
quote, Hygiene.