gpt4 book ai didi

r - 你能更清楚地解释 R 函数运算符中的惰性求值吗?

转载 作者:行者123 更新时间:2023-12-03 23:40:49 27 4
gpt4 key购买 nike

如果我创建一个函数如下:

what_is_love <- function(f) {
function(...) {
cat('f is', f, '\n')
}
}

并用 lapply 调用它: funs <- lapply(c('love', 'cherry'), what_is_love)
我得到意外的输出:
> funs[[1]]()
f is cherry
> funs[[2]]()
f is cherry

但请注意,当您不使用 lapply 时,情况并非如此。 :
> f1 <- what_is_love('love')
> f2 <- what_is_love('cherry')
> f1()
f is love
> f2()
f is cherry

是什么赋予了?

我知道 funs <- lapply(c('love', 'cherry'), what_is_love)可以更完整地写出:
params <- c('love', 'cherry')
out <- vector('list', length(params))
for (i in seq_along(params)) {
out[[i]] <- what_is_love(params[[i]])
}
out

但是当我浏览时,我看到两个函数都有自己的环境:
Browse[1]> out[[1]]
function(...) {
cat('f is', f, '\n')
}
<environment: 0x109508478>
Browse[1]> out[[2]]
function(...) {
cat('f is', f, '\n')
}
<environment: 0x1094ff750>

但是在这些环境中的每一个中, f是一样的...
Browse[1]> environment(out[[1]])$f
[1] "cherry"
Browse[1]> environment(out[[2]])$f
[1] "cherry"

我知道答案是“懒惰的评估”,但我正在寻找更深入的...如何 f最终在两个环境中重新分配?在哪里 f来自?在这个例子中,R 惰性求值是如何工作的?

——

编辑:我知道 the other question关于惰性求值和函数,但它只是说答案是“惰性求值”,而没有解释惰性求值实际上是如何工作的。我正在寻求更深的。

最佳答案

当你做

what_is_love <- function(f) {
function(...) {
cat('f is', f, '\n')
}
}

内部函数为 f 创建一个 shell ,但要注意的是,在您实际使用传递给函数的变量之前,它仍然是一个“ promise ”,实际上并未对其进行评估。如果要“捕获” f 的当前值,那么就需要强制对promise进行求值;您可以使用 force()为此功能。
what_is_love <- function(f) {
force(f)
function(...) {
cat('f is', f, '\n')
}
}
funs <- lapply(c('love', 'cherry'), what_is_love)

funs[[1]]()
# f is love
funs[[2]]()
# f is cherry

force() , f在列表中的两个函数中仍然是一个 promise 。直到您调用该函数时它才会被评估,并且当您调用该函数时,promise 被评估为 f 的最后一个已知值。这是“樱桃”。

正如@MartinMorgran 指出的那样,这种行为在 R 3.2.0 中发生了变化。来自 release notes

Higher order functions such as the apply functions and Reduce() now force arguments to the functions they apply in order to eliminate undesirable interactions between lazy evaluation and variable capture in closures. This resolves PR#16093.

关于r - 你能更清楚地解释 R 函数运算符中的惰性求值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29733257/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com