我想我理解为什么在使用动态范围的语言中允许闭包存在危险。也就是说,似乎你可以关闭变量OK,但是当你尝试读取它时,你只能得到全局堆栈顶部的值。如果其他功能在过渡期间使用相同的名称,这可能会很危险。
我是否错过了其他一些微妙之处?
答案 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。你提到的问题是向上的问题。