【问题标题】:Why is it that a lambda is not a closure and vice versa?为什么 lambda 不是闭包,反之亦然?
【发布时间】:2015-03-01 22:44:49
【问题描述】:

我一直试图得到这个答案一段时间,但我一直无法找到任何能说服我的东西。有人知道这件事的最后一句话吗?有什么简单明了的例子吗?顺便说一句,我已经看到了这个问题: What is the difference between a 'closure' and a 'lambda'?

我找到了非常有趣的答案,但是当谈到我原来的问题时,我就更加困惑了。

非常感谢任何帮助。

【问题讨论】:

  • 您说的是哪种语言。我不知道有任何语言有闭包,其中 lambda 不是闭包。
  • @sepp2k 它们并不完全相同。 lambda 表达式就是代码。闭包是词法范围语言中评估的 lambda 表达式(运行时对象)。
  • @sepp2k 我说的是一般的函数式编程,而不是特定的语言。

标签: lambda functional-programming closures


【解决方案1】:

事实上,很多人都感到困惑,包括您所链接问题的答案中的一些人。

让我重申一下我的回答:lambda 是一种语言构造,用于(匿名)函数表达式,闭包是一种实现技术,用于使本地函数成为一流的。

例如,在函数式语言中,命名函数定义

f x = x + 1              (* 1 *)

通常只是 lambda 表达式的简写:

f = lambda x => x + 1    (* 2 *)

(反之亦然,lambda 可以看作是辅助局部定义的简写,例如,

lambda x => x + 1

相当于一个 let 表达式:

let f x = x + 1 in f

)

换句话说,lambda 只是语法,它们本身并不暗示任何语义。

另一方面,闭包是一种实现局部函数的方法,无论是表示为 lambda 还是以命名形式。例如,考虑:

g x = let h y = x + y in h    (* 3 *)

或等效:

g x = lambda y => x + y       (* 4 *)

(函数式语言甚至允许将后者缩写为

g x y = x + y

)

这里的内部函数引用了外部函数的一个局部变量(参数x)。像g 2 这样的表达式会返回一个函数,但是这个函数的内部表示不能仅仅由h 的“代码”组成,它还必须包含x = 2 的信息。后者称为闭包环境,闭包环境和“代码”这对就是所谓的“闭包”。这个名字来自数学:一个函数对象“关闭”它的环境(来自外部范围的名称),在一个自包含实体的意义上。在实现中,这很重要,以便即使在周围的调用早已返回时,这些函数也能作为独立值持久存在。

所以,如您所见,有些函数写成 lambda(例如上面的 2 和 4),有些函数必须表示为闭包(例如,上面的 3 和 4),但也有可能发生没有另一个(例如,2 或 3)。 (尽管具有一等函数的语言通常将所有函数都视为闭包,但在退化的情况下,它们只是有一个空的闭包环境。)

人们经常混淆这两个概念的原因是许多主流语言没有正确的局部函数概念,可以不受限制地引用局部变量(即它们没有闭包)。然后一些人开始引入 lambda 表达式作为局部函数的 only 适当形式。为了更清楚地说明差异,人们明确地谈论“闭包”,以区别于其他残缺形式的局部函数,就像它们以前存在于一些主流语言中一样。

【讨论】:

  • 一个 lambda 表达式只是代码,而一个计算的 lambda 表达式计算为一个词法范围语言中的闭包。使用动态范围的语言,您可以获得在评估时不是闭包的函数对象。因此,当函数被调用时,创建函数时空闲的变量可能不存在。
猜你喜欢
  • 2018-06-09
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
  • 2012-03-25
  • 2013-10-25
  • 1970-01-01
相关资源
最近更新 更多