вопрос о связывании переменных в общем lisp - PullRequest
7 голосов
/ 22 апреля 2011

Это вопрос о связывании переменных в функции define:

Если я определю функцию «total» следующим образом, x в «total» будет привязан к локальному x в let.

но, если я определю "total" следующим образом, x будет привязан к глобальному x в defvar:

CL-USER> (defvar x 10000) 
X
CL-USER> (let ((x 0))
           (defun total (y)
             (incf x y)))
TOTAL
CL-USER> (total 1)
10001

Почему это?Мне нужно объяснение, чтобы понять это.среда Windows + Emacs + Slime + Sbcl. Спасибо.

1 Ответ

6 голосов
/ 22 апреля 2011

DEFVAR устанавливает символ (здесь, X) как динамическую переменную («особая»). Как только это будет сделано, его динамичность будет сохранена с помощью LET и лямбда-списков (это одна из причин, почему вы всегда называете специальные переменные * earmuffs *). Таким образом, во втором примере X в TOTAL будет просматриваться в динамической среде, в которой вызывается TOTAL. Когда вы вызываете его на верхнем уровне, он видит привязку верхнего уровня X, где он имеет значение 10000. Вы также можете вызвать TOTAL внутри другого LET, который повторно связывает X, и он будет использовать это значение в течение продолжительности:

* (let ((x 1000))
    (total 5)))
1005
* (total 1)
10002

В первом примере X не был отмечен как специальный, поэтому LET связывает его лексически, как обычно. Последующий DEFVAR не оказывает обратного влияния на TOTAL, потому что DEFUN захватил лексическую среду, созданную LET, и будет использовать ее для ссылки на X (в основном, скрывая ее от DEFVAR.)

...