假设我要定义一个名为defsomething
的宏,这样:
(defspecial a x)
...扩展到这个:
(def a (f `a x))
语法引用`a
有一个棘手的部分。我没有看到如何正确地将当前命名空间附加到符号,以便它的行为类似于语法引用。例如:
(defmacro defspecial [var-symbol expr]
`(def ~var-symbol (f '~var-symbol ~expr)))
(defspecial a x)
...扩展为:
(def a (f 'a x))
...这是接近的,但第二个a
不是命名空间限定的。
我知道我可以使用*ns*
:
(defmacro defspecial [var-symbol expr]
`(def ~var-symbol (f (symbol (name (ns-name *ns*)) (name '~var-symbol)) ~expr)))
......但我不喜欢那样;不仅难看,*ns*
可以重新绑定,所以这是可能的:
(binding [*ns* (the-ns 'clojure.core)]
(defspecial a 5))
不幸的是,Clojure显然没有syntax-quote
`
形式,就像它quote
'
一样。那么,我应该如何最好地实现这个宏呢?
答案 0 :(得分:1)
你真的尝试过你给的最后一个例子吗?编译器对*ns*
的绑定发生在编译时,宏扩展也是如此,因此您执行的运行时绑定应该对defspecial
的行为没有影响。