【发布时间】:2013-03-08 00:36:48
【问题描述】:
考虑以下简单函数:
f <- function(x, value){print(x);print(substitute(value))}
参数x 最终将由print 评估,但value 永远不会。所以我们可以得到这样的结果:
> f(a, a)
Error in print(x) : object 'a' not found
> f(3, a)
[1] 3
a
> f(1+1, 1+1)
[1] 2
1 + 1
> f(1+1, 1+"one")
[1] 2
1 + "one"
一切如预期。
现在考虑替换函数中的相同函数体:
'g<-' <- function(x, value){print(x);print(substitute(value))}
(单引号应该是花式引号)
让我们试试吧:
> x <- 3
> g(x) <- 4
[1] 3
[1] 4
到目前为止没有什么异常......
> g(x) <- a
Error: object 'a' not found
这是出乎意料的。名称a 应打印为语言对象。
> g(x) <- 1+1
[1] 4
1 + 1
这没关系,因为x 以前的值是4。请注意通过未计算的表达式。
最终测试:
> g(x) <- 1+"one"
Error in 1 + "one" : non-numeric argument to binary operator
等一下……它为什么要尝试评估这个表达式?
那么问题是:错误还是功能?这里发生了什么?我希望一些 guru 用户能够对 R 的 promise 和惰性评估有所了解。或者我们可能会认为这是一个错误。
【问题讨论】:
-
我可能遗漏了一些非常基本的东西,但在我看来,您的两个函数的行为方式完全相同。当你们所有人
f(a, a)时,您会收到您期望的错误消息。当您致电g(x) <- a时,您会收到完全相同的错误消息,但您并不期望它。这是为什么呢? -
我认为问题在于您认为解释器实际上在做什么。请注意,
'g<-'(x, 1+"one")有效 -
第一条错误消息来自
print(x),而不是来自print(substitute(value))。关键是:a没有定义。在对f的第二次调用中,符号a即使未定义也是可以的,并被打印为语言对象。与电话g(x) <- a比较。 -
@Dason,所以这意味着
g(x) <- y不等于y <- 'g<-'(x,y)。为什么不?当我们在第一次调用中使用替换函数时,还会发生什么? -
这可能是因为当R解析
g(x) <- a将其转换为"g<-"(x,a)时,它会评估a?