2

I'm working in a Coursera course on functional programming and at some point they discuss the difference between call-by-value and call-by-name evaluation techniques. They're some point that confuses me, they say:

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

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

which seems to be a lambda calculus theorem.

Could you explain me what they mean by "the reduced expressions conssist of pure functions"?

4

1 に答える 1

4

純粋な関数とは、副作用 (IO を実行したり、関数に対してローカルではない値を変更したりするなど) のない関数です。純粋な関数の例は次のとおりです。

def inc(x: Int) = x+1

不純な関数の例は次のとおりです。

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

それでは、次の 2 つのメソッドについて考えてみましょう。これらのメソッドは、引数を名前で受け取るか値で受け取るかだけが異なります。

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バージョンは関数を 2 回呼び出して 2 つの結果を追加するのに対し、ByValueバージョンは関数を 1 回呼び出して結果を保存し、それ自体に追加することです。

純粋な関数の場合、これはまったく違いはありません。同じ引数が与えられた場合、常に同じ結果が返されるため、1 回呼び出して保存された結果を 2 回使用するか、2 回呼び出しても違いはありません (パフォーマンスを除く)。

sum不純な関数の場合、関数が呼び出されるたびに変数の値が変更されるため、大きな違いが生じます。

于 2016-09-29T14:50:37.993 に答える