9

我正在尝试以编程方式构建数据日志查询,但一直遇到我将通过示例函数说明的问题:

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

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

 [?entity 3 ?value]

但相反,我得到

[mynamespace/?entity 3 mynamespace/?value]

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

4

2 回答 2

12

就在这里。

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

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

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

(defn test-expr [attribute]
  `[~(quote ?entity) ~attribute ~(quote ?value)])
于 2012-12-07T07:43:11.653 回答
7

您正在寻找的是 Brandon Bloom 的反引号库https://github.com/brandonbloom/backtick

它是为您描述的确切问题而构建的。它提供了一个名为“模板”的命令,该命令的工作方式类似于反引号,但没有命名空间的内容。

在 Clojure 中,准引用和命名空间解析在一个特性中混合在一起。这对于用 Clojure 之类的语言编写宏有很大的好处,它是一种“Lisp-1”(与 Common Lisp 不同,它是一种“Lisp-2”,函数和变量具有单独的命名空间。)

我也同意不要将这些特性混为一谈可能会更好,但它会使在 Clojure 中编写宏变得不那么优雅,所以我可以理解它为什么会这样工作。

于 2012-12-07T15:35:02.943 回答