环境,(en)闭包和框架是如何相关的?

Jos*_*ich 14 environment closures r function frame

我想更好地理解环境,闭包框架是如何相关的.我理解功能闭包包含一个环境,环境包含一个框架和一个外壳,框架包含变量,但我对它们如何相互作用有点模糊.

也许在函数调用期间发生的事情的一个例子会有帮助吗?或者可能是图表?

Tom*_*mmy 10

UPDATE R-lang将environmenta 定义为具有框架.我倾向于认为帧是堆栈帧,而不是从名称到值的映射 - 但是当然有data.frame将列名称映射到向量(然后是一些......).我认为大多数混淆来自于原始S语言(仍然是S-Plus)没有环境对象这一事实,因此所有"框架"基本上都是环境对象现在,除了它们只能作为一部分存在调用堆栈.

例如,在S-Plus中,文档sys.nframe"sys.nframe返回所有帧列表中当前帧的数字索引"....这对我来说听起来非常像堆栈帧...你可以在这里阅读更多关于堆栈帧的信息:http://en.wikipedia.org/wiki/Call_stack#Structure

我扩展了下面的一些解释,并始终使用术语"堆栈框架"(我希望).

结束更新

我会这样解释:

  1. 环境是将变量名称映射到值的对象.每个映射称为绑定.该值可以是实际值或承诺.环境具有父环境(空环境除外).当您在环境中查找符号但未找到该符号时,也会搜索父环境.

  2. 承诺是一种未经评估的表达方式,也是评估表达式的环境.在评估承诺时,它将替换为生成的值.

  3. 闭包是一个函数和定义函数的环境.像lmstats命名空间环境和用户定义函数的函数将具有全局环境 - 但是f在另一个函数中定义的函数g将具有本地环境g作为其环境.

  4. 堆栈帧(或激活记录)代表调用堆栈上的条目.每个堆栈帧都有执行函数的本地环境,以及函数调用的表达式(这样才sys.call有效).

  5. 执行函数调用时,会创建一个本地环境,并将其父级设置为闭包的环境,参数与函数的形式参数匹配,并将这些绑定添加到本地环境(作为promises).不匹配的形式参数被赋予函数的默认值(promises)(如果有的话)并标记为缺失.然后使用此本地环境和调用表达式创建堆栈帧.堆栈帧被推入调用堆栈,然后在此本地环境中评估函数体.

...所以正文中的所有符号都将在本地环境(正式参数和局部变量)中查找,如果在父环境(封闭环境)和父代的父环境中找不到,依此类推,直到找到.

请注意,在这种情况下,不会搜索父堆栈框架的环境.的parent.frame,sys.frame功能得到调用堆栈上的环境-也就是说,呼叫者的环境和调用者的调用者的环境等...

# Here match.fun needs to look in the caller's caller's environment to find what "x" is...
f <- function(FUN) match.fun(FUN)(1:10)
g <- function() { x=sin; y="x"; f(y) }
g() # same as sin(1:10)

# Here we see that the stack frames must also contain the actual call expression
f <- function(...) sys.call()
g <- function(...) f(..., x=42)
g(a=2) # f(..., x = 42)
Run Code Online (Sandbox Code Playgroud)


Ite*_*tor 5

约翰福克斯的扩展描述是否解决了您的问题?

它有漂亮的图表,但没有小马.

Fox&Weisberg的书中还有一个描述,"应用回归的一个R伴侣"(2011),从p开始.417,或第8.9.1节.我认为上述PDF虽然较旧,但可能只是提供信息,如果不是更多(因为图表).对于其他有用的东西,F&W是一本很好的书,我之前已经插了好几次.FWIW,我没有在"坚果壳中的R"一书中找到任何有用的见解.不过,我还没有任何钱伯斯的书.