这是我从#clojure频道学到的宏生成宏:
(defmacro import-alias
[new-name imported]
`(defmacro ~new-name [f# & body#]
`(. ~'~imported ~f# ~@body#)))
(pprint
(macroexpand-1
'(import-alias J Math)))
这扩展为:
(clojure.core/defmacro
J
[f__36239__auto__ & body__36240__auto__]
(clojure.core/seq
(clojure.core/concat
(clojure.core/list '.)
(clojure.core/list 'Math)
(clojure.core/list f__36239__auto__)
body__36240__auto__)))
为什么我们将单元素列表连接在一起?我知道这是一个非常棘手的巫术,我不会在实践中这样做,但我很感兴趣,它是如何实际工作的?
如果我只改变一个引用的位置,那么扩展就完全不同了:
(defmacro import-alias
[new-name imported]
`(defmacro ~new-name [f# & body#]
`(. ~~'imported ~f# ~@body#)))
(pprint
(macroexpand-1
'(import-alias J Math)))
;;; expand:
(clojure.core/defmacro
J
[f__36269__auto__ & body__36270__auto__]
(clojure.core/seq
(clojure.core/concat
(clojure.core/list '.)
(clojure.core/list imported)
(clojure.core/list f__36269__auto__)
body__36270__auto__)))
和
(defmacro import-alias
[new-name imported]
`(defmacro ~new-name [f# & body#]
`(. '~~imported ~f# ~@body#)))
(pprint
(macroexpand-1
'(import-alias J Math)))
;; expand:
(clojure.core/defmacro
J
[f__36323__auto__ & body__36324__auto__]
(clojure.core/seq
(clojure.core/concat
(clojure.core/list '.)
(clojure.core/list
(clojure.core/seq
(clojure.core/concat
(clojure.core/list 'quote)
(clojure.core/list Math))))
(clojure.core/list f__36323__auto__)
body__36324__auto__)))
为什么?