Sylwester 的回答很好地解释了这一点,但在一个具有更明确副作用的示例使这一点更清楚的情况下,请考虑:
CL-USER> (defparameter *foo* (progn (print 'hello) 0))
HELLO
*FOO*
CL-USER> *foo*
0
CL-USER> *foo*
0
在定义*foo*
中,(progn (print 'hello) 0)
被评估一次,因此hello
被打印,值为0
,成为 的值*foo*
。稍后评估*foo*
只是意味着查找*foo*
的值 ( 0
) , not reëvaluating the form that produced its original value. In contrast, consider calling a function whose body is
(progn (print 'hello) 0)`:
CL-USER> (defun foo () (progn (print 'hello) 0))
FOO
CL-USER> (foo)
HELLO
0
CL-USER> (foo)
HELLO
0
CL-USER> (foo)
HELLO
0
每次foo
被调用,(progn (print 'hello) 0)
被评估,所以hello
被打印并被0
返回。看完这个例子,你的代码应该会清楚一点。
(defparameter *lfn*
(let ((count 0))
#'(lambda ()
(incf count))))
(let ...)
被评估一次,并且该评估产生其值的闭包*lfn*
。另一方面,在
(defun testclosure ()
(let ((count 0))
#'(lambda ()
(incf count))))
(let ...)
每次testclosure
调用时都会评估,每次都返回一个新的闭包。