gensym
Clojureでは、マクロを衛生的に保つために、マクロで内部的に使用するシンボルを作成するためにを使用する必要があります。ただし、ネストされた構文引用符で同じ記号を使用する必要がある場合があります。たとえば、値をシンボルにバインドlet
し、展開されたループで3回出力する場合は、次のようにします。
`(let [x# 1]
~@(repeat 3
`(println x#)))
しかし、それは
(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#
異なる構文引用符から作成されたため、フォーム内にネストされたフォームとは異なるシンボルをlet
フォームに生成します。println
それを解決するために、事前にシンボルを生成し、それを構文引用符に挿入することができます。
(let [x (gensym)]
`(let [~x 1]
~@(repeat 3
`(println ~x)))
)
これにより、必要なすべての場所で同じ記号を使用して、正しい結果が生成されます。
(clojure.core/let [G__7 1]
(clojure.core/println G__7)
(clojure.core/println G__7)
(clojure.core/println G__7))
これで、正しい結果が得られますが、コード自体は醜く冗長に見えます。シンボルを「宣言」する必要はありません。インジェクション構文により、マクロの外部から来たか、マクロのどこかで計算されたように見えます。auto-gensym構文を使用できるようにしたいと思います。これにより、これらがマクロ内部シンボルであることを明確にできます。
それで、ネストされた構文引用符でauto-gensymを使用して、それらに同じシンボルを生成させる方法はありますか?