Clojure宏:获取语法引用/名称空间限定符号

时间:2012-11-06 04:46:20

标签: clojure macros

假设我要定义一个名为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 '一样。那么,我应该如何最好地实现这个宏呢?

1 个答案:

答案 0 :(得分:1)

你真的尝试过你给的最后一个例子吗?编译器对*ns*的绑定发生在编译时,宏扩展也是如此,因此您执行的运行时绑定应该对defspecial的行为没有影响。