Search code examples
clojuremacroshygienegensym

Why is next not gensymed?


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#))))

Solution

  • 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.