Scheme R5RS示例中语法规则卫生宏调用中的缺少参数

问题描述 投票:0回答:1

我对Scheme中的卫生宏还有其他问题,请考虑R5RS中的示例>

(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 stmt2 ...)
                      (if test
                          (begin stmt1
                                 stmt2 ...))))))
  (let ((if #t))
    (when if (set! if 'now))
    if))

如果模式具有3个可以匹配空列表的参数和省略号,为什么会匹配?

通过2个参数if(set! if 'now)进行调用。如果可以将...绑定到空列表,则stmt2应该绑定到什么?如果...什么都不是,这是一种非礼貌。是真的吗?

在这种情况下,什么时候应该扩展? stmt2的值是多少?

为什么这不起作用,但是第一个代码起作用?

(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 stmt2 ...)
                      (if test
                          (begin stmt1
                                 stmt2 ...))))))
    (when if 10))

它在Kawa中起作用,但在Guile中不起作用,那是Guile中的bug,实际上它应该像在Kawa中一样起作用?

还有一个问题,为什么它不评估为nil?如果列表中10之后的下一个元素是nil,那么stmt2应该是nil? R5RS在这方面不是很有帮助。

我问这个问题是因为我刚刚在LIPS方案中为宏系统确定了重命名方案,当我进行模式匹配时,我得到了stmt2nil的比较,还剩下... 。在这种情况下,是否应该忽略...而将stmt2设为nil?而且即使模式中少了一个符号,它也应该匹配吗?这确实令人困惑。

最后一个代码片段的扩展应该是什么?

编辑:

再想一想

(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 . stmt2)
                      (if test
                          (begin stmt1
                                 stmt2))))))
    (when if 10))

这在Kawa中有效,并按预期方式返回nil,但在Guile中它抛出异常,我认为Kawa Scheme在以下规范中会更好。

但是,如果没有足够的参数,为什么它甚至与模式匹配?

我对Scheme中的卫生宏还有其他问题,请考虑R5RS中的示例(let-syntax((when(syntax-rules()((when test stmt1 stmt2 ...)(if ...

[
是。我们有一个修饰符...可以改变前面元素的含义,这是非常轻松的。例如。 something .... something基本相似,但它适用于以下结构:

(define-syntax my-let (syntax-rules () ((_ ((a b) ...) body1 bodyn ...) ((lambda (a ...) body1 bodyn ...) b ...))))

注意,我使用body1 ro需要在主体中至少包含一个表达式,因为bodyn ...可以是零个或多个元素。这将变成:

(my-let () test) ==> ((lambda () test))

以及

(my-let ((a b) (c d)) test1 test2) ==> ((lambda (a c) test1 test2) b d)

我的示例无法用cons语法重写,但是基本上使用.的方式与模式中的其余参数和引用中的.的方式相同:

'(a b . (c d)) ; ==> (a b c d)

您的when不能使用多个表达式。例如。 

(let-syntax ((when (syntax-rules () ((when test stmt1 . stmt2) (if test (begin stmt1 stmt2)))))) (define if #t) (when if (display 'true) #t))

想象一下,所有报表绑定也都在r5rs:前缀下。扩展将变为:

(r5rs:if if (begin (display 'true) (#t))) ; ERROR: Application not a procedure: #t

这是正确的:

(let-syntax ((when (syntax-rules () ((when test stmt1 . stmt2) (if test (begin stmt1 . stmt2)))))) (define if #t) (when if (display 'true) #t)) ; ==> #t (prints true)

macros scheme
1个回答
0
投票
是。我们有一个修饰符...可以改变前面元素的含义,这是非常轻松的。例如。 something .... something基本相似,但它适用于以下结构:
© www.soinside.com 2019 - 2024. All rights reserved.