Function definition doesn’t have to be a top-level form, it can even be self-referential. By placing a defun form within a defun form, both forms using the same function-name, we can write a function that, upon being called, redefines itself.
(defun count-to-three ()
(defun count-to-three ()
(defun count-to-three ()
(defun count-to-three ()
nil)
3)
2)
1)
CL-USER> (count-to-three)
1
CL-USER> (count-to-three)
2
CL-USER> (count-to-three)
3
CL-USER> (count-to-three)
NIL
I haven’t figured out how to recursively self-defun in any way that isn’t made obsolete by the existence of outside variables, but I have figured out the next best thing:
(defun secret-message ()
(inform-agents)
(sb-thread:make-thread (let ((std-out *standard-output*))
(lambda () (dotimes (i 5)
(print (- 5 i) std-out)
(sleep 1))
(defun secret-message () nil)))))
CL-USER> (secret-message)
As always, should you or any of your I.M. force be caught or killed, the Secretary will disavow any knowledge of your actions.
This function will self-destruct in five seconds.
Good luck, Jim.
#<SB-THREAD:THREAD RUNNING {1004E4BB33}>
5
4
3
2
1
CL-USER> (secret-message)
NIL