Clojure:宏中的错误。 “没有这样的变化”

时间:2014-01-13 15:46:00

标签: macros clojure lisp

当我在clojure中使用宏时,我遇到了问题。这就是我想要做的。

(defmacro working-example []
  '(+ foo 1))

(defn working-function [foo]
  (working-example))

(working-function 2) ; => 3

(defmacro broken-example [bar]
  `(+ foo ~bar))

(defn broken-function [foo]
  (broken-example 1)) ; => I get error here.

(broken-function 2) ; Should be 3.

我希望破解示例宏只替换文本,就像工作示例一样。为什么它不起作用,我应该怎样才能使它起作用?

1 个答案:

答案 0 :(得分:5)

我对Clojure很新,但我会试着解释一下这里发生了什么。引用和反引用在处理符号方面有所不同。例如,您可以编写导致细微差别的类似代码:

user=> '(+ foo 2)
(+ foo 2)
user=> `(+ foo 2)
(clojure.core/+ user/foo 2)

请注意,只需使用反引号将符号“绑定”到相应的命名空间(clojure.core+userfoo。相反,引用只是将符号视为原样。如果要正确编写损坏的函数,可以使用list语法:

(defmacro broken-example [bar]
  (list '+ 'foo bar))

(defn broken-function [foo]
  (broken-example 1))

(broken-function 2)

现在broken-function输出预期结果。

修改

现在感谢下面的A. Webb评论,您还可以使用以下语法来避免命名空间绑定:

(defmacro broken-example [bar]
  `(+ ~'foo ~bar))