2012-04-23 41 views
6

使用reifyeval很容易在Scala中编写卫生宏。但it's not always possible使用reifyeval在没有通知的情况下确保卫生

因此,如果一个人不能使用它们,那么确保宏观卫生的规则是什么?有没有什么方法可以测试一个宏,以确保没有不良的卫生通过裂缝溜走?

upd。在后来的2.10.0里程碑中,Expr.eval被重命名为Expr.splice

+0

阅读[Wikipedia> Hygienic macro](http://en.wikipedia.org/wiki/Hygienic_macro)可能会有帮助。我没有太多的宏经验,所以我能做的最好的是重新维护Wikipedia的信息。 – 2012-04-23 16:11:30

+0

是的 - 我熟悉以前的Lisp和C++宏。但是,用一种语言工作的东西并不一定直接连接到另一种语言:-) – 2012-04-23 21:17:25

回答

10

Reify是卫生的,因为它将符号与Ident和This树一起保存。

如果您的宏扩展结果没有附加到idents的符号(例如,您只有Ident(“x”)来指定对某个名为x)的引用),则随后的宏扩展的类型检查将绑定x到任意在调用网站的范围内(或者如果该范围没有x,则会收到编译错误)。

相比之下,当您的宏扩展具有它的idents的符号时,typechecker不会尝试重新解析它们,并且只是使用它的内容。这意味着,当您通过表达式并在宏展开中使用结果时,它会将其符号带入呼叫站点。好吧,不是所有的符号,例如不可能引用局部变量或私有/受保护的东西,但是对全局可访问的声明的引用是持久的。

底线是检查你的宏是否卫生,检查你​​的idents和thises是否有附加符号。您可以通过编制或手动将符号分配给手工制作的树木来实现此目的。

1

由于reify是一个宏,我只是看它的实现来找出它的作用。

+0

当然 - 这将是我的下一步行动:-)我不确定我会“只是”看看它 - 实现是相当的参与,并会采取一些分手。 鉴于没有人似乎有任何规则可以处理,我想我会看看我是否可以捕获它们,并在我这样做时发布它们。 – 2012-04-23 21:21:38

相关问题