关于常见lisp中的变量绑定的问题

luo*_*865 7 lisp common-lisp

这是关于函数define中的变量绑定的问题:

如果我像这样定义funcion"total",则"total"中的x将绑定到let中的本地x.

CL-USER> (let ((x 0))
           (defun total (y)
             (incf x y)))
TOTAL
CL-USER> (defvar x 10000)
X
CL-USER> (total 1)
1
Run Code Online (Sandbox Code Playgroud)

但是,如果我像这样定义"total",x将在defvar中绑定到global x:

CL-USER> (defvar x 10000) 
X
CL-USER> (let ((x 0))
           (defun total (y)
             (incf x y)))
TOTAL
CL-USER> (total 1)
10001
Run Code Online (Sandbox Code Playgroud)

为什么这个?我需要一个解释来理解它.环境是windows + emacs + slime + sbcl.Thanks.

Nie*_*jou 6

DEFVAR将符号(此处为X)建立为动态变量("特殊").一旦完成,它的动态性将由LET和lambda列表保留(这就是为什么你总是用*earmuffs*命名特殊变量的一个原因).所以在第二个例子中,TOTAL中的X将在调用TOTAL的动态环境中查找.当你在顶级调用它时,它会看到X的顶级绑定,它的值为10000.你也可以在另一个重新绑定X的LET中调用TOTAL,它将在持续时间内使用该值:

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

在第一个例子中,X没有被标记为特殊,因此LET正常地将其绑定在词汇上.随后的DEFVAR不会追溯性地影响TOTAL,因为DEFUN已经抓住LET创建的词法环境,并将其用于引用X(基本上,将其隐藏在DEFVAR中).