Macros 球拍宏不工作
我以前从未使用过Racket的宏系统,所以请原谅我的无知。我试图在Racket的数据日志系统中动态定义规则,基本上如下所示:Macros 球拍宏不工作,macros,lisp,racket,datalog,hygiene,Macros,Lisp,Racket,Datalog,Hygiene,我以前从未使用过Racket的宏系统,所以请原谅我的无知。我试图在Racket的数据日志系统中动态定义规则,基本上如下所示: (datalog rules (! (:- c a b))) (datalog rules (! (apply :- conclusion premises))) 如果我把这样的东西直接放到代码中,一切都很好。但是,我希望动态生成这些规则。对于常规函数,我只需执行以下操作: (datalog rules (! (:- c a b))) (datalog rules
(datalog rules (! (:- c a b)))
(datalog rules (! (apply :- conclusion premises)))
如果我把这样的东西直接放到代码中,一切都很好。但是,我希望动态生成这些规则。对于常规函数,我只需执行以下操作:
(datalog rules (! (:- c a b)))
(datalog rules (! (apply :- conclusion premises)))
但是数据日志
,
和:-
都是宏,这就不可能了
我的解决方案是编写以下宏:
(define-syntax (make-rule stx)
(syntax-case stx ()
((_ premises conclusion)
#`(datalog rules (! (:- ,conclusion ,@(map (lambda (x) `,x) premises)))))))
这就是所谓的:
(make-rule '(a b) 'c)
但是,在运行时,如果a
和b
都为true,则查询数据日志数据库不会显示任何内容
我试着双引号引用syntax对象,这样我就可以看到得到的输出,结果如下:
'(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))
好的,我想我给你准备好了。这不是卫生问题
#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))
问题在于引用/取消引用。在这里,我只是修改了模板以接受您提供的表单。同样,我不太理解数据日志语言,但这与您在示例中所说的“有效”相同。我对数据日志和宏都不是专家,但这看起来像是一个卫生问题。绑定可能会在后台重命名,您需要使用
语法大小写
或语法解析
表单来打破五定律我使用的是语法大小写。如何打破它?您需要使用和语法来引入不会被宏系统秘密重新标记的绑定。您能给出一个完整的示例吗?我认为我在卫生方面是错的。@law of fives刚刚添加了它。实际上我还有另一个问题——现在我在映射中使用宏,我认为它在逐字解释函数的参数<代码>(map(lambda(x)(make rule(car x)(caddr x)))解析)
--没有像预期的那样工作,因为我相信它将引用的(car x)
解释为结论,然后将caddr x
扩展为前提。有什么提示吗?宏只是将car
等视为任何其他(无意义)标识符,因此您不能真正对宏“参数”使用结构化或解构。它们是语法转换器而不是语义转换器;)。一个选项是生成一个makerules
表单,该表单需要一个更复杂的模式,该模式在内部扩展为上文定义的makerule
。但这取决于您打算如何使用此宏。