2011-12-08 16 views
7

Me encontré con algo extraño, que espero que alguien aquí pueda arrojar algo de luz. Básicamente, cuando una función tiene un argumento cuyo valor predeterminado es el nombre del argumento, suceden cosas extrañas (bueno, extraño de todos modos).Comportamiento inesperado con argumentos predeterminados

Por ejemplo:

y <- 5 

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

f2 <- function(y=y) y^2 

Me considero f y f2 equivalentes; aunque usan nombres de variables diferentes internamente, ambos deben elegir el objeto y en el entorno global para usarlo como el predeterminado. Sin embargo:

> f() 
[1] 25 

> f2() 
Error in y^2 : 'y' is missing 

No estoy seguro de por qué está sucediendo eso.

para hacer las cosas aún más interesante:

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

> f3() 
Error in f3() : 
    promise already under evaluation: recursive default argument reference or earlier problems? 

que esperaba f3 para iniciar un error, pero no que uno!

Esto se probó en R 2.11.1, 2.12.2 y 2.14, en Windows XP SP3 de 32 bits. Solo los paquetes estándar cargados.

+0

el tiempo que querían para codificar ' jogo

Respuesta

1

Los argumentos predeterminados se evalúan dentro del alcance de la función. Su f2 es similar (casi equivalente) para el siguiente código:

f2 = function(y) { 
    if (missing(y)) y = y 
    y^2 
} 

Esto hace que la clara definición del alcance y explica por qué su código no funciona.

Tenga en cuenta que esto es solo verdadero para los argumentos predeterminados; los argumentos que se pasan explícitamente son (por supuesto) evaluados en el alcance de la persona que llama.

La evaluación perezosa, por el contrario, no tiene nada que ver con esto: todos los argumentos se evalúan con pereza, pero llamar f2(y) obras sin queja. Para demostrar que la evaluación perezosa siempre sucede, considere esto:

f3 = function (x) { 
    message("x has not been evaluated yet") 
    x 
} 

f3(message("NOW x has been evaluated") 

Esto imprimirá, en este orden:

x has not been evaluated yet 
NOW x has been evaluated 
Cuestiones relacionadas