闭包和对象

14

函数式编程类似于经典的(马克·吐温类型)。在阅读关于SICP的其他文章时,人们谈论闭包对他们思维的巨大影响,这让我想起了很久以前读过的内容。

闭包是穷人的对象 对象是穷人的闭包

(无法确切记得来源,但可能是程序员罗塞塔石碑、编程禅宗或编程陀螺...谷歌已经变得如此拥挤,无法找到原始来源)

那么,共同编程者们...你们的看法是...闭包是你一直缺少的东西...还是只是一些语法糖,可以由预处理器完成!!

5个回答

23

http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html

祖师Qc Na与他的弟子Anton正在散步。Anton希望能引发祖师的讨论,便问道:“大师,我听说对象是非常好的东西——这是真的吗?”Qc Na怜悯地看着他的弟子回答道:“愚蠢的徒儿——对象只是穷人的闭包。”

受到责备后,Anton向祖师告别,回到自己的房间,决心学习闭包。他仔细阅读了“Lambda:The Ultimate...”系列论文及其相关内容,并用基于闭包的对象系统实现了一个小型Scheme解释器。他学到了很多,并期待着向他的师傅展示自己的进步。

在下一次与Qc Na散步时,Anton试图通过说:“大师,我勤奋地研究了这个问题,现在明白对象确实只是穷人的闭包。”来打动他的师傅。Qc Na挥舞手中的棍子打了Anton一下,说道:“你什么时候才能明白?闭包才是穷人的对象。”就在那一刻,Anton获得了启示。

-- Anton van Straaten


1
这是引用的原始来源还是另一种引用方式? - AnthonyWJones
这个链接信息是这个特定公案的原始来源。它是针对闭包/对象二元性讨论而产生的,因此这个概念已经存在比这个特定的叙述更久了。请点击链接获取完整详情。 - bendin
“Qc Na” / “Anton”这是回调函数吗?我查了一下,只能找到跟案例本身有关的参考资料。 - Eleanor Zimmermann
2
@Elanor Zimmermann 哈哈,只需查看链接即可。Anton 是 Anton van Straaten。Qc 是 Queinnec Christian。Na 是 Norman Adams。 - resgh

4

我在JavaScript中使用闭包已经有很长一段时间了。有时它们会形成一个“对象”,有时它们是向回调提供实例数据的有用方式。

就我而言,它们是工具箱中的另一个有用工具,但它不仅仅是语法糖。语法糖指的是您可以使用另一种更加复杂的语法来合理地完成的某些事情。在不直接支持闭包的语言中实现闭包将非常困难。


更糟糕的是,在不直接支持闭包的语言中实现闭包提供的功能将在任何使用它的地方有效地混淆您的意图。它们确实是“糖”,但当您制作岩糖时,您不能忽视糖的重要性... - Shog9
@Shog9:我完全同意你的第一句话。我不知道我是否同意第二句话,因为我发现很难理解。 - AnthonyWJones
3
抱歉,当字符限制只有300个时,我最终删掉了太多内容。岩糖就是水晶化的糖;如果你不喜欢糖,它就没有意义。许多高级编程结构——闭包、对象——只是与其他程序员交流的工具——糖果。我们写的是岩糖。 - Shog9

3

闭包不仅仅是语法糖,虽然我认为这在一定程度上取决于你对“语法糖”的定义。

对我来说,Java 1.5的for-each就是语法糖,但是比如Ruby块远远超出了这个范畴。闭包提供了方便的抽象层次,对于隐式声明意图非常有用——这是迈向DSL式语法的重要一步。


3

闭包和匿名块是非常重要的编程构造,在Java、C++、C以及其他缺少它们的语言中,我很快就会感到它们的缺乏。它们在异步和事件处理中特别有用。它们还使得接受函数作为参数的函数更加易用,并提供了在不增加语法的情况下做更多事情的选择。(参见:Smalltalk和Scheme)


C# 的委托和 Lambda 表达式已经很好地涵盖了这个问题,不是吗? - krosenvold
委托似乎是一个有趣的特性。我从列表中删除了C#。 - Cheery
@Cherry:为什么你把C#从列表中删除了? - AnthonyWJones
因为委托似乎与闭包和匿名块执行相同的操作。但我不确定,这取决于它们的行为。 - Cheery

2

闭包类似于面向对象语言中的对象。但是函数式语言缺乏子类型和继承。


1
你都知道它们,是吗? - Ingo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接