为什么闭包是 Scala 或任何函数式编程语言的一部分 [已关闭]

why closures are part of scala or any functional programming language [closed]

提问人:Vivek 提问时间:10/18/2020 最后编辑:Dmytro MitinVivek 更新时间:10/18/2020 访问量:233

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

3年前关闭。

根据定义,闭包是

Scala 闭包是使用一个或多个自由变量的函数,该函数的返回值依赖于这些变量。自由变量在闭包函数外部定义,不作为此函数的参数包含在内。

纯函数的定义是

纯函数是仅依赖于其声明的输入及其内部算法来产生其输出的函数。它不会从“外部世界”(函数范围之外的世界)读取任何其他值,也不会修改外部世界的任何值。

当函数式编程都是用纯函数来编写代码时,为什么像闭包这样的概念在函数式编程中是合理的

请帮忙澄清理解

Scala 函数式编程 闭包 pure-function

评论

2赞 Sergio Tulentsev 10/18/2020
不过,Scala 并不声称自己是一种纯粹的函数式语言。
1赞 Vivek 10/18/2020
但是像 Erlang 这样的函数式编程语言也有 Closures.how?
1赞 Sergio Tulentsev 10/18/2020
总的来说,我认为你的假设(“函数式编程就是用纯函数来编写代码”)一开始就是有缺陷的,但我没有足够的理论知识来正确地反驳它。
3赞 Bergi 10/18/2020
您似乎对“它没有从”外部世界“读取任何其他值”感到困惑。这并不意味着不允许纯函数访问在其主体外部定义的变量,而是意味着它不能对有状态自由变量执行“读取”操作。从更高的范围访问闭合常数是完全可以的,并且不会影响纯度。
1赞 Tim 10/18/2020
自由变量可能“在闭包函数之外”,但它们不是“在函数范围之外”。它们必须在范围内,以便对函数可见。

答:

1赞 Dmytro Mitin 10/18/2020 #1

请考虑以下示例

def factorial(n: Int): Int = {
  lazy val loop: (Int, Int) => Int = 
    (i, acc) =>
      if (i == n + 1) acc
      else loop(i + 1, acc * i)

  loop(1, 1)
}

这是阶乘的尾递归版本,从迭代到 。1n

从 FP 的角度来看,这里的所有函数(无论是 Scala 方法还是实际函数)都是纯的,即在相同的输入上,它们返回相同的输出并且没有副作用,它们的调用可以替换为它们的结果(引用透明度)。scala.Function

但是,作为闭包取决于外部作用域的参数(即 )。loopn

从外部范围读取变量(无副作用)(与写入相反)不被视为副作用。

https://alvinalexander.com/scala/fp-book/definition-of-pure-function/

https://en.wikipedia.org/wiki/Pure_function

https://en.wikipedia.org/wiki/Referential_transparency

什么是参考透明度?

https://en.wikipedia.org/wiki/Closure_(computer_programming)

评论

0赞 Tim 10/18/2020
使用 a 而不是 的原因是什么?是否存在性能差异,还是只是风格问题?lazy valdef
0赞 Dmytro Mitin 10/18/2020
@Tim 嗯,一般来说,选择/肯定不是风格问题,因为它们有不同的语义。这里只是为了说明目的,使 lambda/闭包更加明显。通常我会使用方法和嵌套方法。关于性能,方法可以比函数有更好的性能。deflazy val