我正在尝试以编程方式构建数据记录查询,但继续遇到我将使用示例函数说明的问题:
(defn test-expr [attribute]
`[?entity ~attribute ?value]])
当我运行(test-expr 3)时,我希望输出:
[?entity 3 ?value]
但相反,我得到了
[mynamespace/?entity 3 mynamespace/?value]
这显然不是我想要的。有没有办法告诉clojure"请引用列表并扩展我告诉你的变量?"
答案 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中的宏写得不那么优雅,所以我可以看出它为什么会这样运作。