DrRacket中的宏步进器

时间:2012-01-22 14:27:17

标签: macros scheme racket expansion

在链接http://www.ccs.neu.edu/home/ryanc/macro-stepper/tutorial.html上有关于使用宏步进器的说明。

然而,当我要尝试它时,我无法在非零的定义中得到myor的第二次扩展?功能,只有第一个。另外,我没有按钮“上一学期”和“下一学期”。

所以我的问题是:如何配置宏步进器以获得第二次扩展,就像在教程中一样?

2 个答案:

答案 0 :(得分:6)

我假设您的源程序看起来像这样:

#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)))

短篇小说:暂时使用 syntax-case 而不是 syntax-rules ;似乎有一些与宏步进器和语法规则相关的错误。我已经向Racket开发者发送了bug report,所以希望很快就能解决这个问题。上述程序的语法案例版本如下所示。

#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的预发行版下运行程序时,我在Macro Stepper中看到以下内容,Macro隐藏设置为“Standard”:

(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)))))))

我会写一个bug report并将其发送给Racket开发人员。

如果您使用 syntax-case 编写宏,而不是使用语法规则,那么使用宏步进器似乎可以更好地工作。

#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)))

当我逐步完成此操作时,它似乎工作得更好。因此无论触发错误,它似乎都是与Macro Stepper和语法规则的一些交互。因此,请尝试使用 syntax-case

答案 1 :(得分:1)

它对我有用而无需做任何额外的事情。尝试使用最新版本的Racket,同时尝试从菜单中选择其他语言,并确保为您选择的语言选择了debugging