Functions That Redefine Themselves

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

Leave a Reply

Your email address will not be published. Required fields are marked *