Macros 球拍宏不工作

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

我以前从未使用过Racket的宏系统,所以请原谅我的无知。我试图在Racket的数据日志系统中动态定义规则,基本上如下所示:

(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
。但这取决于您打算如何使用此宏。