首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Dr.racket不展开嵌套的宏?

为什么Dr.racket不展开嵌套的宏?
EN

Stack Overflow用户
提问于 2012-11-19 16:11:03
回答 1查看 929关注 0票数 1

我使用的是Dr. Racket,版本5.3.1。我正在尝试使用Macro Stepper功能,但在使用“嵌套”宏时遇到问题。(所谓“嵌套”宏,我指的是展开为包含更多(使用定义的)宏的形式的宏。我不知道这是不是正确的术语)。宏步进程序只扩展这些宏一次,然后就不会继续扩展了。

例如,我在Dr. Racket定义区域中键入以下内容:

代码语言:javascript
复制
#lang racket

(define-syntax foo
  (syntax-rules ()
    ((foo a) 1)
    ((foo a stuff ...) (+ 1 (foo stuff ...)))))

(foo a b c d e)

不出所料,运行此命令将返回5。此外,在交互窗口中输入(expand '(foo a b c d e))也会生成语法'(#%app + '1 (#%app + '1 (#%app + '1 (#%app + '1 '1))))。然而,进入Macro Stepper (具有标准宏隐藏)并按下End按钮,我只看到(+ 1 (foo b c d e))。如果我禁用宏隐藏,我会得到预期的结果,但也会有很多我不想看到的行杂音。

这是一个bug,还是预期的行为?我发誓拉克特医生以前不是这样的。

我实际上在一个月前提交了一份关于这个问题的bug报告(http://bugs.racket-lang.org/query/?cmd=view&pr=13203),但后来我开始重新考虑这是否是一个bug,所以我决定在这里提问。

PS -关于这一点的其他随机注释:

这似乎取决于嵌套宏是否是扩展形式中最外层的表达式。例如,如果我定义(除了foo之外):

代码语言:javascript
复制
(define-syntax bar
  (syntax-rules ()
    ((bar xs ...) (foo xs ...))))

(define-syntax baz
  (syntax-rules ()
    ((baz xs ...) (bar xs ...))))

(baz a b c d e)

然后,宏步进程序显示(baz a b c d e)展开为(bar a b c d e)(foo a b c d e)(+ 1 (foo b c d e)),但随后停止。

前面的示例可能会让您认为它与扩展到自身的宏有关,但事实并非如此。例如,如果我重新定义foo,如下所示:

代码语言:javascript
复制
(define-syntax foo
  (syntax-rules ()
    ((foo a) 1)
    ((foo a stuff ...) (+ 1 (blah stuff ...)))))

使用

代码语言:javascript
复制
(define-syntax blah
  (syntax-rules ()
    ((blah xs ...) 10)))

然后(foo a b c d e)扩展到(+ 1 (blah b c d e)),然后停止。

EN

回答 1

Stack Overflow用户

发布于 2015-08-18 06:54:01

我不确定这是不是一个bug,尽管扩展代码中的foo与原始foo的颜色不同,所以我倾向于认为这是混淆它的原因。

默认情况下,宏步进程序会尝试简化展开的宏以仅显示模块中定义的宏,以及字符串所需的文件(即来自您的“项目”的文件)。这就是似乎要抛弃它的特性。

解决此问题的一种方法(至少在小文件中)是禁用此功能。要执行此操作,请转到窗口左下角,其中显示:Macro hiding:,单击下拉菜单并选择Disable

Macro hiding: -> Disable

从那里,您应该可以看到模块的整个扩展,包括foo的扩展。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13449842

复制
相关文章

相似问题

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