我正在阅读有关评估R编程语言的设计的this paperungated copy),并且无法理解有关词法作用域(或缺少词法作用域)的特定示例。

在第4页上,作者提供了以下使用with函数的示例:

with(formaldehyde, carb*optden)


他们接着说:


精明的读者会注意到上面的示例发生了冲突
我们声称R是词法范围的。通常,R是
从词法上讲,范围一直到不是。 R首先是动态的
语言,可以全面反映正在运行的程序的数据,以及
表示。在上面的示例中,用
通过反思性地操作来规避词汇范围
环境。这是通过结合惰性评估,动态
名称查找,并能够将代码转换为文本并返回:


with.default <- function(env, expr, ...)
  eval(substitute(expr),env, enclose=parent.frame())



该函数使用substitute来检索未评估的分析树
它的第二个参数,然后在环境中用eval对其求值
通过将第一个参数与词汇组成
封闭的环境。 “ ...”用于舍弃所有其他
论点。


在这种情况下,使用with函数如何违反词汇作用域的原理?

最佳答案

通常,在R上下文作用域中进行讨论时,意味着在函数的父环境中查找函数中的自由变量(即,在函数中使用但未在函数中定义的变量),而不是在调用方(也称为父框架),但是with.default中没有自由变量,因此该示例没有说明这种意义上的词法作用域冲突。

例如,这说明了词法作用域:

x <- 1
f <- function() x
g <- function() { x <- 0; f() }
g() # 1


答案为1,因为在定义f的环境中定义了1。如果R使用动态范围而不是词法范围,则答案将为0(使用调用者的环境)。我们可以这样说明R如何模拟动态范围:

f <- function() eval.parent(quote(x))
g() # 0


添加:

@hadley在下面的评论中建议作者可能一直在指的是with.default的第二个实际参数没有按词法评估,并且这种解释似乎很可能。不用相对于周围的词法环境求值,而是使用with.defaultwith.default的第二个实际参数作为表达式读入substitute函数,然后使用eval相对于第一个参数求值。关于词汇作用域的定义应该是什么样的问题,即使在进行了广泛讨论时也很少定义,但有关R的典型讨论将其称为自由变量的处理。参见例如Gentleman & Ihaka

关于r - 了解R中的词法作用域,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20766649/

10-11 06:23