问题描述
是在defun表单求值期间还是在函数应用程序期间创建了局部变量?
解决方法
binding 是比“变量”更有用的术语,它是名称和值之间的关联。变量是Common Lisp中的一种绑定:还有其他绑定。
对于诸如
的功能(defun foo (x)
(let ((y (+ x 2)))
(+ y x)))
然后以(foo (+ 2 1))
之类的格式显示:
- 首先评估
(+ 2 1)
并将其结果3
绑定到函数中的x
; - 然后使用上面的
(+ x 2)
绑定对x
进行求值,其结果5
以y
形式绑定到let
; - 最后,
(+ y x)
是通过上面的两个绑定求值的,其结果8
是函数调用的返回值。
请注意,在其他条件相同的情况下,只要有可能进行引用,便可以从建立绑定开始就对其进行访问:它们具有无限的范围。上面的内容无关紧要,因为函数返回后没有引用的可能性。像
这样的函数确实很重要(defun bar (x)
(lambda (y)
(+ x y)))
由于调用bar
返回的函数引用了其绑定x
,因此只要该函数继续存在,该绑定就必须继续存在。在绑定发生突变的情况下,很容易看出这一点必须成立:
(defun bar (x)
(lambda (y)
(+ y (incf x))))
然后
> (let ((f (bar 0)))
(values (funcall f 1) (funcall f 1)))
2
3
这里还有其他各种情况。