2017-03-09 192 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

请注意,这个问题包含了这个短语“它是否仅适用于函数参数的评估?”我的回答与韦克汉姆的说法并不矛盾。 –