macros - Racket 宏不起作用

标签 macros lisp racket datalog hygiene

我以前从未使用过 Racket 的宏系统,请原谅我的无知。我正在尝试在 Racket 的 Datalog 系统中动态定义规则,基本上是这样的:

(datalog rules (! (:- c a b)))

如果我直接把这样的东西放到代码中,一切都很好。但是,我想动态生成这些规则。对于常规函数,我只会做这样的事情:

(datalog rules (! (apply :- conclusion premises)))

但是 datalog, !:- 都是宏,这不可能。

我的解决方案是编写这个宏:

(define-syntax (make-rule stx)
  (syntax-case stx ()
    ((_ premises conclusion)
      #`(datalog rules (! (:- ,conclusion ,@(map (lambda (x) `,x) premises)))))))

然后这样调用:

(make-rule '(a b) 'c)

然而,当它运行时,当 ab 都为真时,查询 Datalog 数据库不会呈现任何内容。

我尝试用双引号引用语法对象,这样我就可以看到输出的是什么,它是这样的:

'(datalog rules (! (:- c a b)))

所以...如果我直接在我的代码中输入它,那么应该可以工作的究竟是什么!这里发生了什么?这是某种卫生宏观的东西吗?我真的不知道。

谢谢!

编辑:这是问题的完整可运行示例。

#lang racket

(require datalog)

(define rules (make-theory))

(define-syntax (make-rule stx)
  (syntax-case stx ()
    ((_ premises conclusion)
       #`(datalog rules (! (:- ,conclusion ,@(map (lambda (x) `,x) premises)))))))

(make-rule '(a b) 'c)
(datalog rules (? c)) ;;Does not work.

(datalog rules (! (:- c a b)))
(datalog rules (! a) (! b))
(datalog rules (? c)) ;;Works.

最佳答案

好的,我想我已经为您准备好了。这不是卫生问题。

#lang racket
(require datalog)

(define rules (make-theory))

(define-syntax (make-rule stx)
  (syntax-case stx ()
    ((_ (ps ...) c)
     #'(datalog rules (! (:- c ps ...))))))

(datalog rules (! a) (! b))
(make-rule (a b) c)
(datalog rules (? c))

问题在于引用/取消引用。在这里,我只是修改了模板以接受您提供的表格。同样,我并不是真正理解数据记录语言,但这提供了与您在示例中所说的“有效”相同的输出。

关于macros - Racket 宏不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49418783/

相关文章:

LISP:在 Ubuntu 中运行程序

reflection - 编译型动态语言

macros - Racket,将列表转换为值

recursion - 尾调用优化 Racket

macros - Clojure -- 调度宏很特别吗?

c - 如何强制宏不展开

lisp - lisp 中的自定义 '+'(求和)函数

具有 2 个参数问题的 C 预处理器宏

Scala 宏 : constructing an anonymous class

racket - 如何强制结构的字段为某种类型?