为什么 lambda 不是闭包,反之亦然?

Why is it that a lambda is not a closure and vice versa?

一段时间以来,我一直在努力寻找这个问题的答案,但一直找不到任何让我信服的东西。有人知道这件事的最后一句话吗?有没有清楚和简单的例子?顺便说一句,我已经看过这个问题: What is the difference between a 'closure' and a 'lambda'?

我找到了非常有趣的答案,但当涉及到我原来的问题时,我变得更加困惑。

非常感谢任何帮助。

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

让我重申我的回答:lambda 是一种用于(匿名)函数表达式的语言构造闭包是一种实现技术首先制作局部函数-class.

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

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

)

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

另一方面,闭包是实现局部函数的一种方式,无论是表示为 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这样的表达式会return一个函数,但是这个函数的内部表示不能仅仅由h的"code"组成,它还必须包含return这样的信息=20=]。后者称为闭包环境,闭包环境与"code"的对称为"closure"。这个名字来自数学:一个函数对象 "closes" 在它的环境中(来自外部作用域的名称),在某种意义上是一个独立的实体。在实现中,这很重要,以便即使周围的调用很长 returned.

也允许这些函数作为独立值持续存在。

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

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