In Clojure, you need to use gensym to create symbols for internal use in your macros to keep them hygienic. However, sometimes you need to use the same symbol in nested syntax-quotes. For example, if I want to bind a value to a symbol with let and print it three times in an unrolled loop, I'd do

`(let [x# 1]
   ~@(repeat 3
             `(println x#)))

But that would produce

(clojure.core/let [x__2__auto__ 1]
                  (clojure.core/println x__1__auto__)
                  (clojure.core/println x__1__auto__)
                  (clojure.core/println x__1__auto__))

x# generates a different symbol in the let form than in the println forms nested within it - because they were created from different syntax-quotes.

To solve it, I can generate the symbol beforehand and inject it to the syntax-quotes:

(let [x (gensym)]
  `(let [~x 1]
     ~@(repeat 3
               `(println ~x)))
) 

This will produce the correct result, with the same symbol everywhere needed:

(clojure.core/let [G__7 1]
                  (clojure.core/println G__7)
                  (clojure.core/println G__7)
                  (clojure.core/println G__7))

Now, while it does produce the right result, the code itself looks ugly and verbose. I don't like having to "declare" a symbol, and the injection syntax makes it look like it came from outside the macro, or calculated somewhere within in it. I want to be able to use the auto-gensym syntax, which makes it clear that those are macro-internal symbols.

So, is there any way to use auto-gensym with nested syntax-quotes and make them produce the same symbol?

Edit
Report