Неожиданное поведение с параметрами по умолчанию - PullRequest
7 голосов
/ 08 декабря 2011

Я просто наткнулся на что-то странное, что, надеюсь, кто-то здесь сможет пролить немного света. По сути, когда функция имеет аргумент, значением по умолчанию которого является имя аргумента, происходят странные вещи (ну, в любом случае, странные для меня).

Например:

y <- 5

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

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

Я бы посчитал f и f2 эквивалентными; хотя они используют разные имена переменных для внутреннего использования, им обоим следует выбрать объект y в глобальной среде для использования по умолчанию. Тем не менее:

> f()
[1] 25

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

Не уверен, почему это происходит.

Просто чтобы сделать вещи еще интереснее:

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

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

Я ожидал, что f3 выдаст ошибку, но не эту!

Это было протестировано на R 2.11.1, 2.12.2 и 2.14 на 32-битной Windows XP SP3. Загружены только стандартные пакеты.

1 Ответ

2 голосов
/ 01 марта 2017

Аргументы по умолчанию оцениваются внутри области действия функции.Ваш f2 похож (почти эквивалентен) следующему коду:

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

Это делает область видимости более понятной и объясняет, почему ваш код не работает.

Обратите внимание, что это only true для аргументов по умолчанию;аргументы, которые передаются явно, (конечно) оцениваются в области действия вызывающей стороны.

Ленивая оценка, с другой стороны, не имеет к этому никакого отношения: все аргументы вычисляются лениво, но звонок f2(y) работает без нареканий.Чтобы показать, что ленивая оценка всегда происходит, рассмотрим следующее:

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

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

Это напечатает в следующем порядке:

x has not been evaluated yet
NOW x has been evaluated
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...