Это распространенная проблема с динамическими значениями на многих языках (а не только в Racket). Вот что происходит, когда вы оцениваете код:
- Параметр
location
определяется со значением "here"
- Введите
let
...
- Введите
parameterize
...
- Параметр
location
динамически обновляется значение "with a fox"
- Выражение выражения
lambda
оценивается для создания замыкания, которое закрывается над location
- Возвращение из
parameterized
блоков-параметра location
возвращается к своему исходному значению "here"
- Полученный
lambda
обязан get
- Оценки
let
тела ...
- Вы называете
(get)
, и он смотрит на текущее значение location
, что составляет "here"
, и это результат.
Если вы внимательно прочитали документацию по параметрам, это объясняет, что параметр всегда принимает значение ближайшего обновления в стеке. Поскольку ваше обновление со значением "with a fox"
выскочит со стека перед тем, как войти в корпус let
, оно больше не отображается, когда вы делаете фактический звонок get
. Простое исправление, чтобы скопировать значение из параметра и пусть замыкание близко над копией:
(define location (make-parameter "here"))
(let ([get (parameterize ([location "with a fox"])
(let ([loc (location)])
(lambda() loc)))])
(get))
Теперь lambda
закрывает над loc
, который должен иметь ожидаемое значение.