9

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

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

4

2 回答 2

8

我意识到我回答这个问题已经晚了好几年,但我只是在进行网络搜索时遇到了这个问题,我想纠正一些发布在这里的错误信息。

“闭包”仅表示一个可调用对象,它包含代码和为该代码中的自由变量提供绑定的环境。那个环境通常是一个词法环境,但是没有技术上的理由让它不能是一个动态环境。

诀窍是关闭环境而不是特定值的代码。这就是 Lisp 1.5 所做的,也是 MACLisp 为“向下的函数参数”所做的。

您可以通过阅读位于http://www.softwarepreservation.org/projects/LISP/book的 Lisp 1.5 手册了解 Lisp 1.5 是如何做到这一点的

请在附录 B 中特别注意 eval 如何处理 FUNCTION 以及 apply 如何处理 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描述了一种使用浅绑定实现动态闭包的方法

于 2012-06-01T22:39:12.240 回答
7

是的,这是基本问题。然而,术语“闭包”是“词法闭包”的缩写,根据定义,它捕获了它的词法范围。我会将动态范围语言中的东西称为其他东西,例如LAMBDA. 只要您不尝试返回它们,Lambda 在动态范围语言中是完全安全的。

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

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

于 2010-09-10T01:42:57.153 回答