【问题标题】:Racket macros not working球拍宏不起作用
【发布时间】:2018-03-22 00:44:29
【问题描述】:

我以前从未使用过 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 都为 true 时,查询 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.

【问题讨论】:

  • 我既不是数据记录也不是宏专家,但这看起来像是一个卫生问题。绑定可能会在后台重命名,您需要使用 syntax-casesyntax-parse 表单来破坏卫生。
  • @law-of-fives 我正在使用语法大小写。我该如何打破卫生习惯?
  • 您需要使用with-syntax 来引入宏系统不会秘密重新标记的绑定。
  • 你能举一个完整的例子吗?我认为我在卫生方面错了。
  • @law-of-fives 刚刚添加。

标签: macros lisp racket datalog hygiene


【解决方案1】:

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

#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))

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

【讨论】:

  • 我实际上遇到了另一个问题---现在我在map 中使用宏,我认为它是从字面上解释函数的参数。 (map (lambda (x) (make-rule (car x) (caddr x))) parsed) -- 不像预期的那样工作,因为我相信它会将引用的 (car x) 解释为结论,然后将 caddr x 传播为前提。有什么建议吗?
  • 宏只是将car 等视为任何其他(无意义的)标识符,因此您不能真正对宏“参数”使用结构化或解构。它们是语法转换器而不是语义转换器;)。一种选择是创建一个make-rules 表单,该表单期望一个更复杂的模式,该模式在内部扩展为上面定义的make-rule。但这取决于您打算如何使用此宏。
猜你喜欢
  • 1970-01-01
  • 2012-04-09
  • 2012-01-07
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
相关资源
最近更新 更多