Clojureはマクロ定義内のシンボルを名前空間で修飾する。シンボル束縛を回避するためであり、バグを防いでくれるが、次のような書き方をしたいときはNG。
(defmacro foo [x] `(defn ~x [x] x))
user> (macroexpand-1 '(foo aaa)) (clojure.core/defn aaa [user/x] user/x) user> (foo aaa)Can't use qualified name as parameter: user/x [Thrown class java.lang.Exception]
シンボル束縛を強制的に行うためには~'をつける。
(defmacro foo [x] `(defn ~x [~'x] ~'x))
user> (macroexpand-1 '(foo aaa)) (clojure.core/defn aaa [x] x) user> (foo aaa) #'user/aaa user> (aaa 100) 100
使うときは要注意。
尤も、このケースでは(gensym)を使うべきなのだが。。。
→ (追記:2010/03/03)Clojureはマクロ内で使うシンボルの末尾に「#」をつければ勝手にgensymしてくれます。
user> (defmacro foo [x] `(defn ~x [x#] x#)) #'user/foo user> (macroexpand-1 '(foo aaa)) (clojure.core/defn aaa [x__4956__auto__] x__4956__auto__)