A classic example of closing Lisp is the following function that returns a counter:
(defun make-up-counter ()
(let ((n 0))
When called, it increments its counter and returns the result:
CL-USER > (setq up1 (make-up-counter))
#<Closure 1 subfunction of MAKE-UP-COUNTER 20099D9A>
CL-USER > (funcall up1)
1
CL-USER > (funcall up1)
2
When I showed this to a friend unfamiliar with Lisp, he asked how he could copy a counter to create a new independent counter of the same type. This does not work:
CL-USER > (setq up2 up1)
#<Closure 1 subfunction of MAKE-UP-COUNTER 20099D9A>
because up2 is not a new counter, it is just a different name for the same counter:
CL-USER > (funcall up2)
3
Here is my best attempt:
(defun make-up-counter ()
(let ((n 0))
#'(lambda (&optional copy)
(if (null copy)
(incf n)
(let ((n 0))
#'(lambda () (incf n)))))))
To return a copy of the counter, you call it with the argument t:
(defun copy-counter (counter) (funcall counter t))
It works for a first generation copy:
CL-USER > (setq up2 (copy-counter up1))
#<Closure 1 subfunction of MAKE-UP-COUNTER 200DB722>
CL-USER > (funcall up2)
1
, , , 2. , , make-up-counter .
?