2010-09-10 97 views
7

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

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

回答

6

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

(对于一个有趣的想法的实验中,比较在Emacs Lisp的动态范围化的λ返回到返回到在C堆栈分配变量的引用的问题的问题,并且两者是如何在方案是不可能的。)

很久以前,当动态范围的语言比今天少得多时,这就是所谓的funargs problem。你提到的问题是向上的funargs问题。

+3

我不会编辑答案,但:“通常”是错误的 - 闭包始终是“词法闭包”,因为它们通过它的方式关闭表达式词汇环境。至于lambda是安全的 - 不能使用lambdas作为封闭会极大地削弱它们的价值,但即使没有这样做,动态范围对于您的程序的健康本质上是不利的,因为您无法确定任何绑定的含义。 – 2010-09-10 02:32:30

+0

谢谢你的funargs链接。我从来没有学过这个。 – 2010-09-10 03:05:39

+0

@Eli Barzilay:你说的对,我太过分了。我会删除'通常'。至于一般的健康方案,我完全同意,但问题不是一般的。就像我所说的那样,动态范围的lambdas与无限制的指针一样安全...... – 2010-09-11 17:52:48

7

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

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

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

您可以在http://www.softwarepreservation.org/projects/LISP/book

看到Lisp的1.5做这个通过阅读Lisp的1.5手动特别注意在附录B中的eval如何处理功能,以及如何运用手柄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

+0

我意识到我可能会晚几年问这个问题:P,但是你介意解释什么是'make-adder','addx'和'do-test'形成这个[link](http: //wiki.c2.com/?DynamicClosure)你引用了吗?从Lisp 1.5手册来讲,它们不是函数闭包,但是用'lambda'定义。它们看起来更像宏,用单纯的表达式代替(即没有关联环境)。 – wlnirvana 2017-06-22 06:06:53

+0

他们只是正常的,动态范围的功能。被调用时,他们可以访问动态范围内的变量。该程序中唯一的关闭/ funarg是由FUNCTION创建的。 – Glomek 2017-07-14 18:01:20

+0

好的,也许这只是一个术语问题,但我更愿意说没有这种叫做“动态封闭”的东西(我个人认为这比混淆不清)。引用的AIM-199.pdf文件实际上给出了单词闭包的来源,这表明它首先仅用于“闭合”lambda表达式。动态范围的函数,其自由变量逃避到当前的运行时环境,在这个意义上没有关闭,因此在该论文中被称为“打开lambda表达式”。 – wlnirvana 2017-07-21 01:59:11