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

时间:2011-04-22 06:40:25

标签: 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

但是,如果我像这样定义“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

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

1 个答案:

答案 0 :(得分:6)

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

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

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