我正在 Coursera 上学习函数式编程类(class),在某些时候他们讨论了按值调用和按名称调用评估技术之间的区别。他们说,有些问题让我感到困惑:
Both techniques reduce to the same final values as long as:
- the reduced expressions consists of pure functions and
- 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/