【发布时间】:2013-07-06 00:38:25
【问题描述】:
我不确定承诺在 R 中做了什么
如果有人跑
a = lapply(seq_len(2), function(n) { function() {n}})
b = lapply(seq_len(2), function(n) {n})
我们可以看到
a[[1]]() # == 2
b[[1]] # == 1
我知道 R 使用 promise's object 并在其环境中懒惰地评估表达式,但我不明白为什么为每个函数创建的不同 环境 不包含它们自己的 n 值。
[[1]]
function ()
{
n
}
<environment: 0x7f9b2416ad18>
[[2]]
function ()
{
n
}
<environment: 0x7f9b2416ab20>
as.list(environment(a[[1]]))
$n
[1] 2
as.list(environment(a[[2]]))
$n
[1] 2
是否可以通过 lapply 函数以某种方式修复语义?
lapply
function (X, FUN, ...)
{
FUN <- match.fun(FUN)
if (!is.vector(X) || is.object(X))
X <- as.list(X)
.Internal(lapply(X, FUN))
}
<bytecode: 0x7f9b25150f18>
<environment: namespace:base>
PS : 重新聚焦的问题
编辑:具体来说,是否可以编写一个 lapply2 函数,该函数通常“强制”参数具有统一的行为,如:
pl <- lapply (1:3, function(y) { force(y); function(x) pow(x,y) } )
pl <- lapply2(1:3, function(y) { function(x) pow(x,y) } )
【问题讨论】:
-
我有点困惑。是不是因为每个函数的环境只包含承诺,而不是价值,直到需要它才被评估,正如您在上一个问题中所解释的那样?
-
现在您将闭包与值进行比较。我会说这就像苹果和橘子,但是 improbable.com/airchives/paperair/volume1/v1i3/… 。所以我只会说“不要这样做”。
-
是的,问题不在于承诺本身,只要环境得到充分跟踪。
-
我想发布一个更新 - R 中的情况似乎发生了变化,从你的问题开始的代码 sn-ps 现在确实返回了相同的结果。我记得在 Hadley Wickham 的 Advanced R 书中看到了同样的情况,其中代码 sn-p 警告有关承诺的危险实际上正在产生其他东西。据我了解 - lapply 现在可能会强制其 FUN arg 类似于您的 lapply2 建议。
标签: r binding higher-order-functions