I just ran into something odd, which hopefully someone here can shed some light on. Basically, when a function has an argument whose default value is the argument's name, strange things happen (well, strange to me anyway).
For example:
y <- 5
f <- function(x=y) x^2
f2 <- function(y=y) y^2
I would consider f
and f2
to be equivalent; although they use different variable names internally, they should both pick up the y
object in the global environment to use as the default. However:
> f()
[1] 25
> f2()
Error in y^2 : 'y' is missing
Not sure why that is happening.
Just to make things even more interesting:
f3 <- function(y=y) y$foo
> f3()
Error in f3() :
promise already under evaluation: recursive default argument reference or earlier problems?
I expected f3 to throw an error, but not that one!
This was tested on R 2.11.1, 2.12.2, and 2.14, on 32-bit Windows XP SP3. Only the standard packages loaded.
Default arguments are evaluated inside the scope of the function. Your f2
is similar (almost equivalent) to the following code:
f2 = function(y) {
if (missing(y)) y = y
y^2
}
This makes the scoping clearer and explains why your code doesn’t work.
Note that this is only true for default arguments; arguments that are explicitly passed are (of course) evaluated in the scope of the caller.
Lazy evaluation, on the other hand, has nothing to do with this: all arguments are lazily evaluated, but calling f2(y)
works without complaint. To show that lazy evaluation always happens, consider this:
f3 = function (x) {
message("x has not been evaluated yet")
x
}
f3(message("NOW x has been evaluated")
This will print, in this order:
x has not been evaluated yet
NOW x has been evaluated
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With