Нелокальная переменная (Uylktgl,ugx hyjybyuugx)
В теории языков программирования, нелокальная переменная — переменная, которая не определена в локальной области видимости. Хотя термин может относиться к глобальным переменным, он в первую очередь используется в контексте вложенных и анонимных функций, где некоторые переменные могут принадлежать как не локальной так и не глобальной области видимости.
В языке программирования Lua они называются upvalues.[1]
Примеры
[править | править код]Вложенные функции
[править | править код]В примере вложенной функции на языке программирования Python 3, который указан ниже, функция inner
определена в области видимости другой функции — outer
. Переменная x
локальна по отношению к функции outer
, но не локальна по отношению к функции inner
(и не глобальна в то же время):
def outer():
x = 1
def inner():
nonlocal x
x += 1
print(x)
return inner
В языке программирования JavaScript, местонахождение переменной определяется с помощью ближайшего выражения var
для этой переменной. В следующем примере, переменная x
локальна по отношению к функции outer
, так как она содержит выражение var x
, в то же время функция inner
нет. Таким образом x не локальна по отношению к функции inner
:
function outer() {
var x = 1;
function inner() {
x += 1;
console.log(x);
}
return inner;
}
Анонимные функции
[править | править код]В примере на языке Haskell, который следует далее в анонимной функции \x -> x + c
переменная c
нелокальная:
outer = let c = 1 in map (\x -> x + c) [1, 2, 3, 4, 5]
Проблемы с реализацией
[править | править код]Нелокальные переменные являются основной причиной сложности поддержки вложенных, анонимных, высшего порядка и тем самым первого класса функций в языках программирования.
Если вложенная функция или функции (взаимно) рекурсивны, то становиться сложно для компилятора знать точно, где в стеке вызовов была выделена память для нелокальной переменной, так как указатель кадра указывает только на саму локальную переменную вложенной функции и может существовать произвольное количество записей активации в стеке. Обычно эта проблема решается с использованием access links или display registers.
Если вложенная функция передается как аргумент в функцию высшего порядка замыкание, должно быть построено для нахождения нелокальных переменных. Если вложенная функция возвращается как результат из своей внешней функции (или хранится в переменной) нелокальные переменные не будут более доступны в стеке. Вместо этого они должны быть выделены в куче и время их жизни будет дольше времени жизни внешней функции, которая объявила и выделила их. В общих случаях для этого требуется сборщик-мусора.
Примечания
[править | править код]- ↑ Programming in Lua (first edition) Архивная копия от 9 февраля 2023 на Wayback Machine, «27.3.3 — Upvalues Архивная копия от 10 февраля 2023 на Wayback Machine»
Ссылки
[править | править код]- Aho, Lam, Sethi, and Ullman. «7.3 Access to Nonlocal Data on the Stack». Compilers: Principles, Techniques, & Tools. Second edition.