Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用lappy/R表示的承诺_R_Binding_Higher Order Functions - Fatal编程技术网

用lappy/R表示的承诺

用lappy/R表示的承诺,r,binding,higher-order-functions,R,Binding,Higher Order Functions,我不确定这些承诺在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在其环境中使用并懒散地计算表达式,但我不明白为什么为每个函数创建的不同的环境不包含它们自己的n值 [[1]] function () { n } <enviro

我不确定这些承诺在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在其环境中使用并懒散地计算表达式,但我不明白为什么为每个函数创建的不同的环境不包含它们自己的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
[[1]]
函数()
{
N
}
[[2]]
函数()
{
N
}
as.list(环境(a[[1]]))
$n
[1] 2
as.list(环境(a[[2]]))
$n
[1] 2
是否有可能通过lappy函数以某种方式修复语义

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>
lappy
功能(X,乐趣,…)
{

乐趣我发现这种形式更容易理解:

f=function(n) {function() {n}}
x=1
a=f(x)
x=2
a()
[1] 2
文档的关键部分是

调用函数时,参数匹配,然后 形式上的论据是有承诺的 为该形式参数和指向环境的指针提供 从中调用的函数存储在promise中

在调用
a=f(x)
之后,函数参数
n
绑定到一个名为
x
的承诺,并指向全局环境
.GlobalEnv


在您的
lappy
示例中,匿名函数
function(n){function(){n}
每次都从全局环境调用。这就是为什么列表中的每个元素
a
都获得相同的
n值的原因:它来自全局环境。我不知道如何通过重写lappy来改变这种行为。

我不久前发表了一条评论,认为这可能是最近版本的情况
R
的版本,但这里有一个官方证据表明
lappy
现在的行为与您的
lapply2
版本完全相同,该版本取自

  • 高阶函数,如apply函数和Reduce()现在将参数强制应用于它们应用的函数,以消除闭包中惰性求值和变量捕获之间不必要的交互。这解决了PR#16093

我有点困惑。这不是因为每个函数的环境只包含承诺,而不包含值吗?正如您在上一个问题中所解释的,在需要时才对其进行评估?现在您正在比较闭包和值。我想说这就像苹果和桔子,但是。所以我只说“不要这样做。”是的,问题不在于承诺本身,只要环境得到了充分的跟踪。我想发布一个更新-看起来R中的情况已经发生了变化,从问题开始的代码片段现在确实返回了相同的结果。我记得在Hadley Wickham的Advanced R书中看到了相同的结果,其中有一个关于dan的代码片段警告承诺的实现实际上产生了其他东西。据我所知,lapply现在可能会强制其有趣的参数,类似于您的lapply2建议。这可能就是发生的情况。但在其他语言中实现闭包似乎很奇怪。根据定义,当给定相同的参数时,函数应该始终返回相同的结果这太棒了!谢谢你提到它。然后它将更像是在闭包后保留词法范围的常规函数语言。非常成功
f=function(n) {function() {n}}
x=1
a=f(x)
x=2
a()
[1] 2