Честно говоря, я не уверен, что полностью понимаю, что значит для привязки быть «динамической» по сравнению с «лексической». Но я понимаю, что когда я использую defvar
или defparameter
для определения привязки, 1. она объявляет глобальную переменную 2. привязка объявляется «специальной», чтобы ее можно было скрыть новой локальной привязкой, например.
(defvar *x* 3)
(defun f () *x*)
(f) ;=>3
(let ((*x* 2)) (f));=>2
Теперь мой вопрос: возможно ли иметь локальную привязку (т. е. привязку, которая не загрязняет глобальную среду), которая имеет то же свойство (т. е. может быть затенена «внешними»/«более новыми» привязками)?
Пример:
(special-binding ((x 1)) (defun f () x))
(f);=>1
x;=>error, no binding in the global environment
(let ((x 2)) (f));=>2
Я пытался использовать объявления (special x)
в блоке let
или (locally (declare (special x)) ...)
, но, похоже, это не создает закрытие (запрос значения переменной из функции, определенной таким образом, вызывает ошибку «Unbound-Variable»).