Динамическая область видимости — глубокая привязка против поверхностной привязки

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

а) глубокое связывание

б) неглубокое связывание?

x: integer := 1
y: integer := 2

procedure add
  x := x + y

procedure second(P:procedure)
  x:integer := 2
  P()

procedure first
  y:integer := 3
  second(add)

----main starts here---
first()
write_integer(x)

person John Jiang    schedule 18.11.2009    source источник
comment
Это Питон? ваш вопрос язык агностик? пожалуйста уточни   -  person Shimmy Weitzhandler    schedule 27.12.2009


Ответы (3)


Глубокая привязка связывает среду в момент передачи процедуры в качестве аргумента.

Неглубокая привязка связывает среду в момент фактического вызова процедуры.

Таким образом, для динамической области видимости с глубокой привязкой, когда добавление передается в секунду, среда имеет значение x = 1, y = 3, а x — это глобальный x, поэтому он записывает 4 в глобальный x, который был получен write_integer.

Неглубокая привязка просто проходит вверх, пока не найдет ближайшую переменную, соответствующую имени, поэтому ответ будет равен 1.

person John Jiang    schedule 18.11.2009
comment
Для мелкой привязки, если бы я поместил write_integer(y) внутри второй процедуры (до P() ), я бы получил 3 или 2 ? Также для неглубокой привязки могу ли я не изменить значение глобальной переменной? - person vvMINOvv; 14.02.2012
comment
Динамическая область с неглубокой привязкой напечатает 5. Это связано с тем, что динамическая область использует привязки (комбинации переменных и значений) из метода, из которого она вызывается. Таким образом, динамическая область с неглубокой привязкой будет использовать привязку x = 2, в отличие от динамической области с глубокой привязкой, которая будет использовать (как сказал @jjia6395) x = 1 (привязка, когда add было передано в метод second в качестве параметра). - person toinetoine; 09.10.2014
comment
@AntoineDahan нет, если second динамически вводит новую привязку для новой переменной, которая называется x (о чем свидетельствует использование x:integer := 2 вместо x := 2), поэтому add (вызывается из second, пока second жив) изменяет динамически созданные x на 5. Но write_integer(x) ссылается на глобальный x. Итак, этот псевдокод вводит в заблуждение. он должен был использовать = в определениях, например x:integer = 1, и := в мутирующих присваиваниях, например x := x + y. - person Will Ness; 29.12.2015
comment
Тем не менее, я возражаю против такого неправильного использования терминологии — в контексте LISP, где они впервые появились, термины «глубокий» и «мелкий» — это просто методы реализации для динамической или лексической области видимости, и их можно использовать для реализации оба, поэтому они неотличимы внутри программы, если они реализованы правильно. То, что здесь называется глубокой привязкой, является просто недоразумением - вместо этого следует говорить о свободном времени разрешения переменных и делать его явным, написав вместо этого second( closed(add,(x,y)) ). В обоих случаях это по-прежнему динамическое разрешение имен. Вы просто хотите 2 заморозить их. Так что заморозь их. Явно! - person Will Ness; 29.12.2015

а) В глубоком связывании мы имеем дело со средой добавления, в которой x ссылается на глобальный x, а y ссылается на y, локальный для первого (последняя выполненная функция, которая имеет объявление y)

x (глобальный) = x (глобальный) + y (локальный): x = 1 + 3 = 4

b) В неглубокой привязке мы имеем дело со средой second, в которой x ссылается на x, локальный для второго, а y ссылается на y, локальный для первого (последняя выполненная функция, которая имеет объявление y)

х (локальный) = х (локальный) + у (локальный): х = 2 + 3 = 5

НО: write_integer(x) выводит глобальный x, равный 1

Ну наконец то

a) 4

b) 1

person El Hadji Bassirou Toure    schedule 03.10.2020

неглубокая привязка должна быть 5. определения: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=15&lngWId=6

person pranav    schedule 13.12.2011
comment
Нет, при неглубокой привязке выводит 1, как говорит jjia6395. Это связано с тем, что вызов P() изменяет локальный x на second, который затем исчезает, когда возвращается second. Вызов write_integer(x) печатает глобальный x, который не был изменен. - person ruakh; 07.02.2012