【问题标题】:Macro stepper in DrRacketDrRacket 中的宏步进器
【发布时间】:2012-02-16 05:16:34
【问题描述】:

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

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

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

【问题讨论】:

  • 您可能想尝试#racket freenode irc 频道。这类问题将受益于 StackOverflow 并没有真正提供的来回对话。
  • 是的,丹,我知道。但是,不幸的是,我不能在那里问我的问题,因为我被 Racket 用户组禁止(Shriram Krishnamurthi 讨厌我,因为我批评了他们的网络框架)。
  • @Greg H:是的,我非常感谢 dyoo,我通过支持他的回答来表达这一点。我不知道如何将他的答案标记为已接受(找不到那个按钮)
  • 在upvote/downvote按钮附近,你看到复选标记的轮廓了吗?如果您单击它,它将变为纯绿色,并且您已接受答案。

标签: macros scheme racket expansion


【解决方案1】:

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

【讨论】:

  • 我在 Windows 7 上运行 DrRacket 5.2,语言是#lang racket 这是截图:uploadscreenshot.com/image/705182/3970725
  • @RacketNoob:看起来您正在尝试通过模块扩展而不是宏扩展。
  • 抱歉,我无法获得 myor 的第二次扩展(无论我做什么,第一次单击后按钮“Step ->”都是灰色的)。有人可以提供详细的分步说明如何完成所有宏扩展步骤吗?
【解决方案2】:

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

#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;似乎有一些与宏步进器和语法规则相关的错误。我已将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)))

下面是更长的故事......

当我在 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)))))))

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

如果您使用 syntax-case 编写宏,而不是 syntax-rules,那么它似乎更适合使用 Macro Stepper。

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

当我逐步完成时,它似乎工作得更好。所以无论是什么触发了这个错误,它似乎是与宏步进器和 syntax-rules 的一些交互。因此,请尝试改用 syntax-case

【讨论】:

  • 酷。如果答案可以接受,请将此问题标记为已回答,以便将其从 SO 上的“未回答”列表中删除。
猜你喜欢
  • 1970-01-01
  • 2012-06-13
  • 2011-08-20
  • 2014-01-04
  • 1970-01-01
  • 2017-03-22
  • 2018-12-15
  • 2014-02-01
相关资源
最近更新 更多