nam*_*min 24
卫生通常用于宏的上下文中.卫生宏不使用可能存在干扰扩展代码的变量名称.这是一个例子.假设我们想or用宏定义特殊形式.直观地说,
(or a b c ... d)会扩展到类似的东西(let ((tmp a)) (if tmp a (or b c ... d))).((or)为简单起见,我省略了空案例.)
现在,如果名称tmp实际上是在代码中添加的,就像在上面描绘的扩展中一样,它将不卫生,而且很糟糕,因为它可能会干扰另一个具有相同名称的变量.说,我们想评估
(let ((tmp 1)) (or #f tmp))
Run Code Online (Sandbox Code Playgroud)
使用我们的直观扩展,这将成为
(let ((tmp 1)) (let ((tmp #f)) (if tmp (or tmp)))
Run Code Online (Sandbox Code Playgroud)
在tmp从宏阴影最外面的tmp,所以结果是#f代替1.
现在,如果宏是卫生的(并且在Scheme中,它在使用时会自动出现syntax-rules),那么tmp您将使用保证不会出现在代码中其他任何位置的符号,而不是使用扩展名称.您可以gensym在Common Lisp中使用.
Paul Graham的On Lisp在宏上提供了高级材料.
如果你想象一个宏被简单地扩展到它被使用的地方,那么你也可以想像,如果你使用一个变量a在您的宏,有可能已经是一个变量a,在其中使用了宏定义的地方.
这是不是在a你想要的!
一个像这样的事情不可能发生的宏观系统被称为卫生.
有几种方法可以解决这个问题.一种方法是在宏中使用非常长,非常神秘,非常难以预测的变量名称.
一个稍微更精致的版本是gensym一些其他宏系统使用的方法:代替你,程序员提出一个非常长,非常神秘,非常难以预测的变量名称,你可以调用gensym生成一个非常长,非常非常长的函数为您提供神秘,非常不可预测且唯一的变量名称.
就像我说的那样,在一个卫生的宏观系统中,这种碰撞一开始就不会发生.如何使宏观系统卫生本身就是一个有趣的问题,计划社区已经花了几十年时间研究这个问题,并且他们不断提出更好,更好的方法.
| 归档时间: |
|
| 查看次数: |
5570 次 |
| 最近记录: |