使用宏生成core.logic语句

时间:2015-04-21 08:36:28

标签: clojure clojure-core.logic

我正在尝试通过“填充空白”来动态构建core.logic语句。这是一个简单的例子:

(def number 42)
(def stmt `(run* [q] (== q ~number))
(eval stmt)

但是我得到clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: No such var: user/q, compiling:(null:20:12)

我尝试过引用,取消引用和非引用拼接的所有组合,但我无法弄明白。我该如何插入q

(并且,回过头来,正在建立这样的陈述是正确的方法吗?)

2 个答案:

答案 0 :(得分:4)

由于您使用的是syntax-quote,因此在当前命名空间中引用符号q

引用它不合格,但不引用语法报价引用本身:

(def stmt `(run* [~'q] (== ~'q ~number)))

或生成符号

(def stmt `(run* [q#] (== q# ~number)))

答案 1 :(得分:0)

如果您的逻辑语句存储为字符串,则可以使用read-string获取Clojure表单,然后在其上调用eval

(def number 42)
(def stmt-as-str "(run* [q] (== q number))")
(eval (read-string stmt-as-str))
> (42)

或者,如果它只是一种形式:

(def stmt-as-form '(run* [q] (== q number)))
(eval stmt-as-form)
> (42)

注意:`~~@通常用于宏定义。