首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >语法中缺少参数-方案R5RS示例中的规则卫生宏调用

语法中缺少参数-方案R5RS示例中的规则卫生宏调用
EN

Stack Overflow用户
提问于 2020-04-13 19:35:44
回答 1查看 54关注 0票数 0

我还有一个关于方案中卫生宏的问题,以R5RS为例

代码语言:javascript
复制
(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 stmt2 ...)
                      (if test
                          (begin stmt1
                                 stmt2 ...))))))
  (let ((if #t))
    (when if (set! if 'now))
    if))

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

它是用两个参数if(set! if 'now)调用的。如果...可以绑定到空列表,那么stmt2应该绑定到什么?如果.只是没什么。这是真的吗?

在这种情况下,什么时候应该扩大?stmt2的价值是什么

为什么这不起作用,但第一段代码却起作用?

代码语言:javascript
复制
(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 stmt2 ...)
                      (if test
                          (begin stmt1
                                 stmt2 ...))))))
    (when if 10))

它在Kawa工作,但在欺骗中不起作用,这是不是骗人的错误,实际上应该像在Kawa那样工作呢?

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

我之所以问这个问题,是因为我刚刚在LIPS方案中为我的宏系统完成了重命名方案,当我进行模式匹配时,我得到了stmt2nil的比较,还有...。在这种情况下,...应该被忽略,stmt2应该是nil吗?即使图案上少了一个符号,它也应该匹配吗?这真是让人费解。

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

编辑:

再想一想

代码语言:javascript
复制
(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 . stmt2)
                      (if test
                          (begin stmt1
                                 stmt2))))))
    (when if 10))

这在Kawa中工作,并按预期返回nil,但在Guile中抛出异常,我认为Kawa方案在遵循规范方面更好。

但是,如果没有足够的论据,它为什么还要匹配模式呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-13 21:42:48

是。我们有一个修饰符...来改变前面元素的含义,这是非常不容易的。例如:something ...基本上与. something相似,但它适用于这样的结构:

代码语言:javascript
复制
(define-syntax my-let
  (syntax-rules ()
    ((_ ((a b) ...)
        body1 bodyn ...)
     ((lambda (a ...) 
        body1 bodyn ...) 
      b ...))))

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

代码语言:javascript
复制
(my-let ()
  test)
==> 
((lambda () test))

以及

代码语言:javascript
复制
(my-let ((a b) (c d))
  test1 test2)
==> 
((lambda (a c)
   test1 test2)
 b 
 d)

我的示例不能用con语法重写,但基本上使用.的方式与模式中的rest参数和引用中的.一样:

代码语言:javascript
复制
'(a b . (c d)) 
; ==> (a b c d)

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

代码语言:javascript
复制
(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 . stmt2)
                      (if test
                          (begin stmt1
                                 stmt2))))))
    (define if #t)
    (when if (display 'true) #t))

假设所有报表绑定也都存在于r5rs:前缀下。这一扩展将成为:

代码语言:javascript
复制
(r5rs:if if
         (begin (display 'true)
                (#t)))
; ERROR: Application not a procedure: #t

这是正确的:

代码语言:javascript
复制
(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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61195399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档