为什么clojure将名称空间限定符添加到反引号内的名称?

时间:2012-12-07 07:13:25

标签: macros clojure datomic

我正在尝试以编程方式构建数据记录查询,但继续遇到我将使用示例函数说明的问题:

(defn test-expr [attribute]
  `[?entity ~attribute ?value]])

当我运行(test-expr 3)时,我希望输出:

 [?entity 3 ?value]

但相反,我得到了

[mynamespace/?entity 3 mynamespace/?value]

这显然不是我想要的。有没有办法告诉clojure"请引用列表并扩展我告诉你的变量?"

2 个答案:

答案 0 :(得分:9)

是的,有。

(defn test-expr [attribute]
  `[~'?entity ~attribute ~'?value])

这里首先取消引用语法引用,然后再次引用符号(~'构造)。结果是无名称空间的符号。

它等同于以下内容,它解释了它的工作原理:

(defn test-expr [attribute]
  `[~(quote ?entity) ~attribute ~(quote ?value)])

答案 1 :(得分:6)

你正在寻找的是Brandon Bloom的反击图书馆https://github.com/brandonbloom/backtick

它是为您描述的确切问题而构建的。它提供了一个名为' template'的命令。它的作用就像反击,但没有命名空间。

在Clojure中,quasiquotation和名称空间解析在一个功能中混合在一起。这对于像Clojure这样的语言编写宏有很大的好处,Clojure是一个" Lisp-1" (与Common Lisp相反,它是一个" Lisp-2",具有单独的函数和变量名称空间。)

我也同意最好不要混淆这些功能,但它会使Clojure中的宏写得不那么优雅,所以我可以看出它为什么会这样运作。