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调用时都会评估,每次都返回一个新的闭包。