[英]Call-by-value and by-name equivalence
我正在Coursera函數編程課程中工作,有時他們會討論按值調用和按名稱調用評估技術之間的區別。 他們說這是令我困惑的一點:
只要滿足以下兩種條件,這兩種技術都會減少到相同的最終值:
- 約簡表達式由純函數和
- 兩次評估均終止
這似乎是λ演算定理。
您能否解釋一下“簡化表達式由純函數組成”是什么意思?
純函數是沒有副作用的函數(例如執行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
現在,如果我們將這兩個函數與pure函數一起使用,則結果是相同的:
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
更改sum
變量的值,因此差異很大。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.