Search code examples
common-lisp

can a Common Lisp lambda function return itself?


Okay- this might sound silly, but actually...

Imagine, you have the idea of implementing a finite state machine with functions, representing the current state (I call them state-functions forthwith).

A state-function takes an optional input event as an argument and returns (among other things), the new state function, which (and here we are at the point of this question) can be a new state (i.e. a new state-function) or if the state has not changed... itself!

(defun define-state (name acceptor)
  #'(lambda (context in-event)
      (multiple-value-bind (new-state? out-events new-context)
          (funcall acceptor context in-event)
        (values
          (if new-state? new-state? !!!this lambda !!!!)
          out-events
          new-context
          name))))

I know, I could wiggle around the problem but having this notion intrigued me and I wonder if any of you guys knows, if and how this is possible.

The only option, I currently can think of is to not define the return value as a lambda but instead use (labels ((state-func ...)) ...) instead. But maybe that would be cheating already?!


Solution

  • The easiest thing is to pass the function itself as an argument, which is sort-of the U combinator. So given

    (lambda (self ...) ...)
    

    define (I don't have an implementation to hand, so this may be broken)

    (defun funcall/U (f &rest arguments)
      (apply f f arguments))
    

    and now just call it with funcall/U. In particular if your functions want to recurse they now do it with funcall/U:

    (lambda (self ...) ... (funcall/U self ...) ...)
    

    What you describe with (defvar ...) ... (setf ...) is essentially how Scheme's letrec works by the way:

    (letrec ((x (lambda (...) ... (x ...)))) ...)
    

    turns into (something like)

    (let ((x <illegal>))
      (set! x (lambda (...) ... (x ...)))
      ...)