Clojure > Archives > 2010/05/03

2010/05/03 14:14:38 UTCfatrow
#
(defmacro aaa [x]
  `(let [mem# (atom {})]
     (swap! mem# assoc :a ~x)))
#
こんなマクロがあったとして、これを (aaa (aaa 1)) のようにネストして呼び出した時、mem# で自動生成したシンボルが外側も内側も同じ名前になっちゃうんですが、シンボルの自動生成ってこういうものでしたっけ?
#
user> (use 'clojure.contrib.pprint)
user> (use 'clojure.contrib.macro-utils)
#
user> (pprint (mexpand-all '(aaa (aaa 1))))
(let*
 [mem__1966__auto__ (clojure.core/atom {})]
 (clojure.core/swap!
  mem__1966__auto__
  clojure.core/assoc
  :a
  (let*
   [mem__1966__auto__ (clojure.core/atom {})]
   (clojure.core/swap! mem__1966__auto__ clojure.core/assoc :a 1))))
nil
#
確かにこの例だと、内側で外側の mem__1966__auto__ を使うことはないので問題ないのですが、引数で与えられた式を分解してその中に自分の mem# で作ったシンボルを埋め込むという変態的なマクロの場合、本来の意図と異なってしまいます。