关闭和动态范围?

时间:2010-09-10 01:17:28

标签: lisp scope closures dynamic-scope

我想我理解为什么在使用动态范围的语言中允许闭包存在危险。也就是说,似乎你可以关闭变量OK,但是当你尝试读取它时,你只能得到全局堆栈顶部的值。如果其他功能在过渡期间使用相同的名称,这可能会很危险。

我是否错过了其他一些微妙之处?

2 个答案:

答案 0 :(得分:7)

我意识到我多年来一直在回答这个问题,但我在进行网络搜索时遇到了这个问题,我想纠正这里发布的一些错误信息。

“Closure”只是指一个可调用对象,它包含代码和为该代码中的自由变量提供绑定的环境。这种环境通常是一个词汇环境,但没有技术上的理由说明为什么它不能成为一个动态的环境。

诀窍是关闭环境中的代码而不是特定的值。这就是Lisp 1.5所做的,以及MACLisp为“向下的funargs”做的事情。

通过阅读http://www.softwarepreservation.org/projects/LISP/book

上的Lisp 1.5手册,您可以看到Lisp 1.5是如何做到这一点的

在附录B中特别注意eval如何处理FUNCTION以及如何应用处理FUNARG。

您可以使用http://c2.com/cgi/wiki?DynamicClosure

中的动态闭包获得编程的基本风格

您可以从ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdf

深入了解实施问题

现代动态范围语言通常使用浅层绑定,其中每个变量的当前值保存在一个全局位置,函数调用将旧值保存在堆栈上。在http://www.pipeline.com/~hbaker1/ShallowBinding.html

中描述了使用浅绑定实现动态闭包的一种方法

答案 1 :(得分:6)

是的,这是基本问题。然而,术语“封闭”是“词汇封闭”的缩写,by definition captures its lexical scope。我会用动态范围的语言来调用其他东西,比如LAMBDA。 Lambda在动态范围的语言中是完全安全的,只要你不试图返回它们。

(对于一个有趣的思想实验,比较在Emacs Lisp中返回动态范围的lambda的问题与在C中返回对堆栈分配的变量的引用的问题,以及如何在Scheme中都不可能。)

很久以前,当具有动态范围的语言比现在少得多时,这被称为funargs problem。你提到的问题是向上的问题。