1

假设我想定义一个名为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-quotefor `likequote的形式'。那么,我应该如何最好地实现这个宏呢?

4

1 回答 1

1

你真的试过你给出的最后一个例子吗?编译器的绑定*ns*发生在编译时,宏扩展也是如此,因此您所做的运行时绑定应该对defspecial.

于 2012-11-06T06:16:49.033 回答