我假设你的源程序看起来像这样:
#lang racket
(define-syntax myor
(syntax-rules ()
[(myor e) e]
[(myor e1 . es)
(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
短篇小说:使用语法大小写而不是语法规则暂时;似乎存在一些与宏步进器和语法规则相关的错误。我已经发送了致 Racket 开发者,希望这个问题能尽快得到解决。这语法大小写上述程序的版本如下所示。
#lang racket
(define-syntax (myor stx)
(syntax-case stx ()
[(_ e) #'e]
[(_ e1 . es)
#'(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
下面是更长的故事...
当我在 5.2.1 预发行版下运行您的程序时,我在宏步进器中看到以下内容,并将宏隐藏设置为“标准”:
(module anonymous-module racket
(#%module-begin
(define-syntax myor
(syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(let:26 ([r:26 (negative? r)]) (if:26 r:26 r:26 (myor:26 (positive? r)))))))
这看起来是错误的。它仅扩展了一种用途myor出到用途if。很奇怪!
让我们看看 Racket 5.2 下的情况......
(module anonymous-module racket
(#%module-begin
(define-syntax myor
(syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r) (let ([r (negative? r)]) (if r r (myor (positive? r)))))))
啊。好的,我可以确认我看到了与您在 Racket 5.2 以及预发行版中看到的相同问题。
该错误似乎与“宏隐藏”功能的行为有关,该功能在设置为标准时试图不让您因完整扩展而不知所措。如果将其设置为“禁用”,您将看到宏调试器将显示扩展的完整、不加修饰的荣耀,并且它确实包含我们期望看到的扩展:
(module anonymous-module racket
(#%module-begin
(define-syntaxes (myor)
(lambda (x)
; ... I'm omitting the content here: it's way too long.
))
(define-values:20 (nonzero?)
(lambda:21 (r) (let-values:22 (((r) (#%app:23 negative? r))) (if r r (#%app:24 positive? r)))))))
我会写一个并将其发送给 Racket 开发人员。
如果您使用以下方式编写宏语法大小写,相对于语法规则,它似乎与宏步进器配合使用效果更好。
#lang racket
(define-syntax (myor stx)
(syntax-case stx ()
[(_ e) #'e]
[(_ e1 . es)
#'(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
当我完成这个步骤时,它似乎工作得更好。因此,无论触发该错误的是什么,它似乎都是与宏步进器的某种交互,并且语法规则。所以尝试使用语法大小写反而。