scala - 按值调用和按名称等效

标签 scala functional-programming lambda-calculus callbyname call-by-value

我正在 Coursera 上学习函数式编程类(class),在某些时候他们讨论了按值调用和按名称调用评估技术之间的区别。他们说,有些问题让我感到困惑:

Both techniques reduce to the same final values as long as:

  1. the reduced expressions consists of pure functions and
  2. both evaluations terminate

这似乎是一个 lambda 演算定理。

你能解释一下“由纯函数组成的简化表达式”是什么意思吗?

最佳答案

纯函数是没有副作用的函数(例如执行 IO 或更改非函数本地的任何值)。纯函数的一个例子是:

def inc(x: Int) = x+1

不纯函数的一个例子是:

var sum = 1
def addToSum(x: Int) = {
    sum += x
    sum
}

现在让我们考虑以下两种方法,它们的区别仅在于它们是按名称还是按值获取参数:

def doubleByValue(x: Int) = x + x
def doubleByName(x: =>Int) = x + x

现在,如果我们将这两者与纯函数一起使用,结果是相同的:

doubleByValue(inc(2)) // => 6
doubleByName(inc(2)) // => 6

但是如果我们将它们应用于不纯函数,结果会有所不同:

sum = 1 // Let's reset sum, so the result isn't affected by previous uses
doubleByValue(addToSum(2)) // => 6, the value of `sum` is now 3
sum = 1 // Let's reset sum, so the result isn't affected by previous uses
doubleByName(addToSum(2)) // => 8, the value of `sum` is now 5

区别在于,ByName 版本调用该函数两次并将两个结果相加,而 ByValue 版本调用该函数一次,保存结果并将其添加到自身中.

对于纯函数来说,这绝对没有区别 - 给定相同的参数,它将始终返回相同的结果,因此无论您调用它一次并使用保存的结果两次还是调用它两次(除了性能)。

对于不纯函数来说,它会产生很大的差异,因为每次调用函数时 sum 变量的值都会发生变化。

关于scala - 按值调用和按名称等效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39773244/

相关文章:

Python:嵌套的 lambdas -- `s_push: parser stack overflow Memory Error`

haskell - 为什么第一个 Haskell 函数无法处理无限列表,而第二个代码段在无限列表中成功?

language-agnostic - 为什么只可以添加功能语言列表?

scala - 递归遍历 Scala 列表

scala - Akka HTTP 中的编码

scala - 如何并排组合两个流?

functional-programming - lambda 演算问题

lambda-calculus - Lambda 微积分缩减步骤

scala - 克服 Akka Persistence 中对持久消息类的更改

java - 从 rdd 对象文件创建数据框