Почему (define (hn) (f 0)) оценивается в 100 при вызове (h 10)? - PullRequest
0 голосов
/ 27 сентября 2018
(define n 100)
(define (f a) n)
(define (g n) n)
(define (h n) (f 0))

Почему (define (h n) (f 0)) оценивается в 100 вместо 10 при вызове (h 10)?

При вызове (h 10) будет ли n переопределяться как 10 или все еще 100?Как насчет (g 10)?

1 Ответ

0 голосов
/ 27 сентября 2018

Таким образом, когда вы создаете процедуру и вводите привязку, она доступна только в пределах этой привязки:

((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 является ближайшей.

...