参数默认值出现意外行为

Hon*_*Ooi 7 r

我只是遇到了一些奇怪的东西,希望这里有人可以解释一下.基本上,当一个函数有一个参数的默认值是参数的名字时,会发生奇怪的事情(好吧,对我来说很奇怪).

例如:

y <- 5

f <- function(x=y) x^2

f2 <- function(y=y) y^2
Run Code Online (Sandbox Code Playgroud)

我会考虑f并且f2是等同的; 虽然它们在内部使用不同的变量名称,但它们都应该y在全局环境中拾取对象以用作默认值.然而:

> f()
[1] 25

> f2()
Error in y^2 : 'y' is missing
Run Code Online (Sandbox Code Playgroud)

不知道为什么会这样.

只是为了让事情变得更有趣:

f3 <- function(y=y) y$foo

> f3()
Error in f3() : 
  promise already under evaluation: recursive default argument reference or earlier problems?
Run Code Online (Sandbox Code Playgroud)

我期望f3抛出一个错误,但不是那个!

这是在32位Windows XP SP3上的R 2.11.1,2.12.2和2.14上测试的.仅加载标准包.

Kon*_*lph 3

默认参数在函数范围内计算。你的f2代码类似于(几乎等效)以下代码:

\n\n
f2 = function(y) {\n    if (missing(y)) y = y\n    y^2\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这使得范围更清晰,并解释了为什么您的代码无法\xe2\x80\x99 工作。

\n\n

请注意,这适用于默认参数;显式传递的参数(当然)是在调用者的范围内计算的。

\n\n

另一方面,惰性求值与此无关:所有参数都被惰性求值,但调用可以f2(y)毫无怨言地工作。为了表明惰性求值总是发生,请考虑以下内容:

\n\n
f3 = function (x) {\n    message("x has not been evaluated yet")\n    x\n}\n\nf3(message("NOW x has been evaluated")\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将按以下顺序打印:

\n\n
x has not been evaluated yet\nNOW x has been evaluated\n
Run Code Online (Sandbox Code Playgroud)\n