R 中的返回函数 - 绑定何时发生?

returning functions in R - when does the binding occur?

与其他函数式语言一样,return函数在 R 中很常见。例如,在训练模型后,您想要 return 一个 "predictor" 对象,它本质上是一个函数,给定新数据,returns 预测。当然,在其他情况下这也是有用的。

我的问题是 returned 函数中值的绑定(例如求值)何时发生。

举个简单的例子,假设我想要一个包含三个函数的列表,每个函数都略有不同,具体取决于我在创建函数时设置的参数值。这是一个简单的代码:

function.list = list()
for (i in 1:3) function.list[[i]] = function(x) x+i

所以现在我有三个功能。理想情况下,第一个 returns x+1,第二个计算 x+2,第三个计算 x+3

所以我预计:

function.list[[1]] (3) = 4
function.list[[2]] (3) = 5

等等

不幸的是,这并没有发生,上面列表中的所有函数都计算相同的 x+3。我的问题是为什么?为什么 i 的值的绑定这么晚,因此列表中的所有函数都相同?我该如何解决这个问题?

编辑: rawr 对类似问题的 link 很有见地,我认为它解决了问题。这是 link: Explain a lazy evaluation quirk

然而,我检查了我上面给出的代码,那里建议了修复,但它仍然不起作用。当然,我在这里错过了一些非常基本的东西。谁能告诉我这是什么?这是 "fixed" 代码(仍然不起作用)

function.list = list()
for (i in 1:3) { force(i); function.list[[i]] = function(x) x+i}

仍然function.list[[1]] (3) 给出 6 而不是预期的 4。 我还尝试了以下方法(例如将 force() 放入函数中)

function.list = list()
for (i in 1:3) function.list[[i]] = function(x) {force(i);x+i}

怎么回事?

这是一个使用 for 循环的解决方案,使用 R 3.1:

> makeadd=function(i){force(i);function(x){x+i}}
> for (i in 1:3) { function.list[[i]] = makeadd(i)}
> rm(i) # not necessary but causes errors if we're actually using that `i`
> function.list[[1]](1)
[1] 2
> function.list[[2]](1)
[1] 3

makeadd 函数在具有本地 i 的上下文中创建添加函数,这就是它起作用的原因。如果没有 R 3.2 中的 force,知道这是否有效会很有趣。我总是用武力,卢克....