惰性评估和承诺数据结构

Lazy evaluation and promise data structure

自从我第一次在 Advanced R 上阅读它以来,我一直在努力研究 promise 的应用。有人提到 promise 是一种支持惰性求值的数据结构。惰性评估的概念非常清楚,因为函数参数仅在访问时才评估。但是,在某些示例中,我只是无法发现承诺的存在,并且 how/where 它被评估了。考虑 Advanced R 中的以下示例:

y <- 10
h02 <- function(x) {
  y <- 100
  x + 1
}

h02(y)
[1] 11

它是 returns 11 而不是 101,显然当我们将全局环境中已经存在的 y 之类的变量分配给 x 时,它会在功能。 所以我想知道是一个承诺总是涉及某种赋值,或者每个表达式都可以是一个承诺,以及我们如何检测它们的存在。 提到它们是在函数的调用环境中评估的。所以第二个问题是它们的评估环境是否与普通参数不同,因为用户定义的参数是在函数外部评估的。

还有一个例子,我不明白为什么它涉及惰性评估,我们只看到Calculating...一次。

double <- function(x) {
message("Calculating...")
x * 2
}
h03 <- function(x) {
c(x, x)
}
h03(double(20))
Calculating...
[1] 40 40

如果我在这里听起来有点混乱,我很抱歉,我明白了,但它从来没有完全理解,我想寻求一些解释,我非常感谢。

非常感谢您

当 h02 中的 y 等对象在函数中创建时,它是在该函数的本地执行 frame/environment 中创建的(每次函数 运行).创建的对象不同于任何其他环境中的同名对象。

关于 h03 一旦承诺被强制执行,即被评估,它的值被存储在承诺的 value 组件中并且它的 evaled 组件被设置为 TRUE 以便在进一步访问时它没有有待再次评价。

函数的参数是承诺,但通常不是其他对象。使用 pryr 检查对象。

library(pryr)

f <- function(x) { 
  z <- 1

  cat("is_promise(z):", is_promise(z), "\n")

  cat("is_promise(x):", is_promise(x), "\n")
  cat("before forcing - promise_info(x):\n")
  print(promise_info(x))

  force(x)
  cat("after forcing - promise_info(x):\n")
  print(promise_info(x))

  delayedAssign("w", 3)
  cat("is_promise(w):", is_promise(w), "\n")

  invisible()
}
a <- 3
f(a)

给予:

is_promise(z): FALSE 
is_promise(x): TRUE 
before forcing - promise_info(x):
$code
a

$env
<environment: R_GlobalEnv>

$evaled
[1] FALSE

$value
NULL

after forcing - promise_info(x):
$code
a

$env
NULL

$evaled
[1] TRUE

$value
[1] 3

is_promise(w): TRUE