了解 R 中的惰性求值

Understanding lazy evaluation in 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 调用,即使它的结果没有被使用。

有人可以确切地解释一下这是如何工作的,或者指出详细解释的方向吗?

类似问题:

正如您已经发现的那样,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 在创建时不会被求值,delayedAssign() 只会返回求值 x 的承诺,并且仅当我们实际需要 [=15= 的值时],在这种情况下,为了确定其长度,x 被评估。

表达式是放在函数中还是在全局环境中执行都没有关系,所以你在示例中将表达式封装在函数中并没有真正添加任何东西,这就是为什么我排除它。但如果你想确定,试试:

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