Нелокальная переменная

Из Википедии, бесплатной энциклопедии

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

В языке программирования 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.

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

Примечания

[править | править код]