The classic example of a Lisp closure is the following function that returns a counter:
(defun make-up-counter ()
(let ((n 0))
#'(lambda () (incf n))))
When called it increments its count 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 who is unfamiliar with Lisp he asked me how he could copy a counter to create a new, independent counter of the same type. This doesn't work:
CL-USER > (setq up2 up1)
#<Closure 1 subfunction of MAKE-UP-COUNTER 20099D9A>
because up2 isn't a new counter, it's just a different name for the same counter:
CL-USER > (funcall up2)
3
Here's 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 a 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
but it obviously won't work if you try to copy up2. I can't see how to get it to work properly, because the definition of make-up-counter needs to have a copy of itself inside its own definition.
Any suggestions?