Как связаны среды, (en) замыкания и связанные рамки?

Я хочу лучше понять, как окружения, закрытия, и frames. Я понимаю, что закрытие функций содержит среду, среды содержат фрейм и оболочку, а фреймы содержат переменные, но я немного нечеткий, как они взаимодействуют друг с другом.

Возможно, пример того, что происходит во время вызова функции, поможет? Или, может быть, диаграмма?

Ответы

Ответ 1

UPDATE R-lang определяет environment как имеющий фрейм. Я склонен думать о кадрах как о кадрах стека, а не о сопоставлении от имени к значению - но тогда есть, конечно, data.frame, который сопоставляет имена столбцов векторам (а затем и некоторым...). Я думаю, что большая часть путаницы исходит из того факта, что исходный S-язык (и еще S-Plus) не имел объектов окружения, поэтому все "кадры" были по существу тем объектами среды, за исключением того, что они могли существовать только как часть стека вызовов.

Например, в S-Plus документ для sys.nframe говорит: "sys.nframe возвращает числовой индекс текущего кадра в списке всех кадров".... для меня это звучит очень много, как фреймы стека... Здесь вы можете узнать больше о фреймах стека: http://en.wikipedia.org/wiki/Call_stack#Structure

Я расширил некоторые пояснения ниже и последовательно использовал термин "стековый фрейм" (надеюсь).

END UPDATE

Я бы объяснил их следующим образом:

  • Среда - это объект, который сопоставляет имена переменных значениям. Каждое отображение называется привязкой. Значение может быть либо реальной стоимостью, либо обещанием. У среды есть родительская среда (кроме пустой среды). Когда вы просматриваете символ в среде и его не обнаруживаете, также просматриваются родительские среды.

  • Обещание - это неоценимое выражение и среда, в которой можно оценить выражение. Когда обещание оценивается, оно заменяется сгенерированным значением.

  • Закрытие - это функция и среда, в которой была определена функция. Функция типа lm будет иметь среду пространств имен статистики, а определяемая пользователем функция будет иметь глобальную среду, но функция f определенный в рамках другой функции g, будет иметь локальную среду для g в качестве среды.

  • Фрейм стека (или запись активации) - это то, что представляет записи в стеке вызовов. Каждый кадр стека имеет локальную среду, в которой выполняется функция, и выражение вызова функции (так что работает sys.call).

  • Когда выполняется вызов функции, создается локальная среда с родительским набором, установленным в среду закрытия, аргументы сопоставляются с формальными аргументами функций, и эти привязки добавляются в локальную среду (как promises). Непревзойденным формальным аргументам присваиваются значения по умолчанию (promises) функции (если они есть) и помечены как отсутствующие. Затем создается кадр стека с этой локальной средой и выражением вызова. Фрейм стека выталкивается в стек вызовов, а затем тело функции оценивается в этой локальной среде.

... поэтому все символы в теле будут просматриваться в локальной среде (формальные аргументы и локальные переменные), а если они не найдены в родительской среде (которая является средой закрытия) и родительской родительской средой, и поэтому пока не будет найден.

Обратите внимание, что исходная среда фрейма стека НЕ в этом случае. Функции parent.frame, sys.frame получают среды в стеке вызовов, то есть среду вызывающего абонента и среду вызывающего абонента и т.д.

# Here match.fun needs to look in the caller caller environment to find what "x" is...
f <- function(FUN) match.fun(FUN)(1:10)
g <- function() { x=sin; y="x"; f(y) }
g() # same as sin(1:10)

# Here we see that the stack frames must also contain the actual call expression
f <- function(...) sys.call()
g <- function(...) f(..., x=42)
g(a=2) # f(..., x = 42)

Ответ 2

Есть ли это расширенное описание John Fox, чтобы ответить на ваши вопросы?

У него хорошие диаграммы, но нет пони.

Существует также описание в Фокс и книга Вайсберга "Сопутствующая регрессия" (2011), начиная с p, 417 или раздел 8.9.1. Я думаю, что вышеприведенный PDF, хотя и старше, вероятно, так же информативен, если не больше (из-за диаграмм). F & W - хорошая книга, в которую я подключил пару ранее, для других полезных вещей. FWIW, я не нашел полезной информации в книге "R в двух словах". Тем не менее, у меня пока нет книг из палат.