Форма eval должна оценивать данную форму в нулевой лексической среде, я не понимаю, что ожидаю
Скажем, у меня есть специальный var:
(defvar x 20)
то я делаю следующее:
(let ((x 1)) (eval '(+ x 1))
который оценивается в 2.
Согласно CLHS, eval "Оценивает форму в текущей динамической среде и нулевой лексической среде". Итак, я ожидаю получить 21 вместо 2.
Я что-то пропустил?
Теперь, если у меня нет динамической привязки для символа y, оценка
(let ((y 1)) (eval '(+ y 1))
Я получаю условие: "Переменная Y несвязана", что имеет смысл, поскольку для y нет динамической привязки.
Примечание. Я использую SBCL 1.0.57
Оцените свою помощь заранее!
Ответы
Ответ 1
в вашем примере x
есть special
, что означает, что он связан в динамической среде
y
не является особым, поэтому он связан в лексической среде
поэтому во время первого eval
среды могут быть представлены следующим образом:
dynamic environment: { x : 1 } -> { x : 20, ...other global variables... } -> nil
lexical environment: nil
символ x
является специальным, поэтому eval
смотрит вверх x
в текущую динамику
окружающей среды и находит x = 1
Предполагая, что он был запущен в том же lisp как последний пример, среда вашего второго eval
выглядит так:
dynamic environment: { x : 20, ...other global variables... } -> nil
lexical environment: { y : 1 } -> nil
символ y
не является особым, поэтому eval
смотрит y
в нулевом значении
лексическая среда - не текущая лексическая среда - и ничего не находит.
это имеет смысл, когда вы понимаете, что lisp обычно скомпилирован, а лексический
среда может быть оптимизирована до простых инструкций mov
в некоторых случаях.
Ответ 2
DEFVAR
объявляет свои переменные специальными. Во всем мире. Вы также можете легко удалить это.
Это также причина, по которой вы никогда не должны использовать общие имена, такие как x
, i
, list
как имена переменных для DEFVAR
. Убедитесь, что вместо этого вы используете *x*
, *i*
и *list*
. В противном случае все переменные, даже локальные, с этими общими именами будут объявлены специальными.