使用宏生成 core.logic 语句

Generate core.logic statements using macros

我正在尝试通过 "filling in the blanks" 动态构建 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

(并且,退后一步,建立这样的陈述是正确的方法吗?)

如果您的逻辑语句存储为字符串,您可以使用 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)

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

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

引用它不合格,但不引用它而不是语法引用引用本身:

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

或生成符号

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