(defun morris-counter ()
"Returns a closure which accepts two messages
:PLUS - probabilistically increments counter
:SIZE - returns approximate # of times :PLUS was sent
Any other message raises an error."
(let ((c 0))
(lambda (msg)
(ecase msg
(:plus (when (zerop (random (expt 2 c)))
(incf c)))
(:size (1- (expt 2 c)))))))
(defvar *mc* (morris-counter))
(dotimes (i 12 t) (funcall *mc* :plus))
(pprint (funcall *mc* :size))
KGRlZnVuIG1vcnJpcy1jb3VudGVyICgpCiAgIlJldHVybnMgYSBjbG9zdXJlIHdoaWNoIGFjY2VwdHMgdHdvIG1lc3NhZ2VzCiAgICAgOlBMVVMgLSBwcm9iYWJpbGlzdGljYWxseSBpbmNyZW1lbnRzIGNvdW50ZXIKICAgICA6U0laRSAtIHJldHVybnMgYXBwcm94aW1hdGUgIyBvZiB0aW1lcyA6UExVUyB3YXMgc2VudAogICBBbnkgb3RoZXIgbWVzc2FnZSByYWlzZXMgYW4gZXJyb3IuIgogIChsZXQgKChjIDApKQogICAgKGxhbWJkYSAobXNnKQogICAgICAoZWNhc2UgbXNnCiAgICAgICAgKDpwbHVzICh3aGVuICh6ZXJvcCAocmFuZG9tIChleHB0IDIgYykpKQogICAgICAgICAgICAgICAgIChpbmNmIGMpKSkKICAgICAgICAoOnNpemUgKDEtIChleHB0IDIgYykpKSkpKSkKCihkZWZ2YXIgKm1jKiAobW9ycmlzLWNvdW50ZXIpKQooZG90aW1lcyAoaSAxMiB0KSAoZnVuY2FsbCAqbWMqIDpwbHVzKSkKKHBwcmludCAoZnVuY2FsbCAqbWMqIDpzaXplKSk=