惰性评估和承诺数据结构
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
自从我第一次在 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