Here x
is gensymned because some expression passed to and
can have x
in it and to avoid that conflict. Then why is next
not gensymed? Couldn't next
lead to variable capture?
(defmacro and
([] true)
([x] x)
([x & next]
`(let [and# ~x]
(if and# (and ~@next) and#))))
x
is not gensymmed, and shouldn't be. The gensymmed thing here is and#
, which is gensymmed for the usual reason: it is a synthetic binding introduced into the caller's scope for the macro's internal-only usage. x
and next
are none of these things: they are not introduced as bindings, nor are they for the macro's internal-only usage. They are code snippets (a form and a seq of forms) supplied by the caller, intended to be present in the expanded body for the caller's purposes.