我认为当使用递归来使用 auto-gensym(使用 #
语法)时,它会覆盖自身,这似乎是一个错误。jumar 确认这发生在 1.10.3、1.6.0、1.3.0 和 1.0.0 中。
(defmacro recursive-macro-1 [[x & more :as xs] acc]
(if (seq xs)
`(let [x# ~x]
(recursive-macro-1 ~more (conj ~acc x#)))
acc))
(defmacro recursive-macro-2 [[x & more :as xs] acc]
(if (seq xs)
(let [gx (gensym 'x)]
`(let [~gx ~x]
(recursive-macro-2 ~more (conj ~acc ~gx))))
acc))
(comment
(recursive-macro-1 [1 2] []) ;; => [2 2]
(recursive-macro-2 [1 2] []) ;; => [1 2]
)
我预计 recursive-macro-1
应该与 recursive-macro-2
生成相同的结果,但您可以看到,从运行 clojure.walk/macroexpand-all 在这些形式上,影子阻止了这一点。
;; auto-gensym - the name of the local binding is the same in the nested let*
(let* [x__10885__auto__ 1]
(let* [x__10885__auto__ 2]
(conj (conj [] x__10885__auto__) x__10885__auto__)))
;; gensym
(let* [x11095 1]
(let* [x11096 2]
(conj (conj [] x11095) x11096)))