2017-03-09 109 views
6

我想了解R中懶惰評估的工作原理。它只適用於函數參數的評估嗎?因爲我明白,例如瞭解R中的懶惰評估

f <- function(x = x, y = x*2) { 
    c(x, y) 
} 

f(2) 
[1] 2 4 

但是在其他語言中,例如, Haskell懶惰的評估意味着函數調用只有在實際使用時纔會被評估。所以,我希望這樣的事情在瞬間運行:

g <- function(x) { 
    y <- sample(1:100000000) 
    return(x) 
} 

g(4) 

但它清楚地計算,即使其結果並不習慣的sample電話。

難道有人可以解釋這是如何工作的,或者指向我詳細解釋的方向?

類似的問題:

Question with similar wording, but different problem

回答

7

正如你已經發現,R不會在一般意義上使用懶評價。但是,[R確實提供了這個功能,如果你需要它,由功能delayedAssign()如下圖所示:

> system.time(y <- sample(1E8)) 
    user system elapsed 
    7.636 0.128 7.766 
> system.time(length(y)) 
    user system elapsed 
     0  0  0 
system.time(delayedAssign("x", sample(1E8))) 
    user system elapsed 
    0.000 0.000 0.001 
> system.time(length(x)) 
    user system elapsed 
    7.680 0.096 7.777 

正如你所看到的,y立即評估,進而確定y長度不花時間的。 x另一方面,不創建時評估,只有承諾評估xdelayedAssign()返回,並且只有當我們實際需要值x,在這種情況下,以確定其長度,x進行評估。

表達式放置在函數中還是在全局環境中執行並不重要,因此將表達式封裝到您在示例中執行的函數中並沒有真正添加任何內容,這就是爲什麼我排除它。但是,如果你要確定,請嘗試:

a.f <- function(z) { delayedAssign("x", sample(1E8)); return(z+1) } 
system.time(a.f(0)) 
    user system elapsed 
     0  0  0 
+0

我指的是哈德利韋翰的書,他提到: 「默認情況下,R函數的參數是懶惰的,他們只是評估,如果實際使用」。最新版本是不是真的呢? – Sarang

+0

請注意,這個問題包含了這個短語「它是否僅適用於函數參數的評估?」我的回答與韋克漢姆的說法並不矛盾。 –