Таким образом, когда вы создаете процедуру и вводите привязку, она доступна только в пределах этой привязки:
((lambda (w) (+ w 10)) 2) ; ==> 12
w ; ERROR: Undefined variable (it only exists inside the lambda)
Вы можете переименовать любой параметр, если вы переименуете все его использование.Например.это точно так же:
((lambda (w2) (+ w2 10)) 2) ; w renamed to w2 and has not effect on the outcome.
На самом деле, многие компиляторы переименовывают все идентификаторы, чтобы они были уникальными.Сейчас я сделаю это с вашим кодом:
(define n_1 100)
(define (f_1 a_1) n_1)
(define (g_1 n_2) n_2)
(define (h_1 n_3) (f_1 0))
(h_1 10) ; ==> 100
Это тот же код, что и в вашем вопросе.Все, что я сделал, это переименовал, чтобы привязки не скрывались новыми замыканиями, использующими те же имена.
Теперь вы понимаете, почему (h_1 10)
теперь оценивает до 100, когда нет скрытых привязок?
Забавный факт: в языке LISP без замыканий мы имеем динамическое связывание.Там переменные, созданные последними во время выполнения, определяют, что такое n
.В динамической схеме моя перезапись будет работать так же, как в обычной лексической схеме, но ваш исходный код будет оценивать (h 10) ; ==> 10
, поскольку локальная динамическая привязка n
к 10 является ближайшей.