[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Continuation objects: a proposal

Gee, seeing how BIND-HANDLER works reminds me of an idea I had a few
years ago, and suggests that it might be easier to implement than I
would have guessed.  It's simply stated: I want to make continuations
behave like objects in the T sense: so they have a default behavior
that happens when you funcall them directly, but there is also a
provision for the user to define operations on them.  It might look
something like this:

(define (foo)
  (catch top-level
        ((punt (top-level)))
      (... hairy expression that calls BAR ...))))

(define (bar)
  ... (if something-or-other
          (catch c (punt c))) ...)

This is to be read as follows: PUNT is defined as an operation on the
continuation passed to the hairy expression (and, by inheritance, as
it were, to all continuations whose default continuation is that one,
just as BIND-HANDLER entry functions are inherited).  Then BAR calls
PUNT on such a continuation, in turn causing TOP-LEVEL to be invoked,
which immediately returns from FOO.

This use of a continuation operation is a lot like a dynamically-bound
signal handler.  Note that in fact it has just the properties that you
want in such a thing: the continuation passed to the call to PUNT
inside BAR will have visible any operations BAR may have defined (in
Common Lisp terms, "PUNT will be invoked in the dynamic environment in
force at the point of invocation"), and PUNT could choose to invoke
that continuation rather than TOP-LEVEL (which would be like a
condition handler returning rather than THROWing).

Continuation operations could almost be used to implement dynamic
binding, except for one thing: either the syntax for referencing
dynamically-bound "variables" would be different from that for
referencing normal variables -- this would be my preference -- or else
a variable that one wanted to use as a special variable would have to
be defined as something like a "symbol macro" (yuck), so that *FOO*
would expand into something like (CATCH C (*FOO* C)).

Personally, I would like to see these continuation operations
implemented and BIND thrown out, or at least relegated to those very
few instances when what you really need is literally a SET with an
UNWIND-PROTECT to undo it.

By the way, I don't intend the syntax and naming of the example above
to be a formal proposal.  WITH-CONTINUATION-OPERATIONS might plausibly
be called just HANDLING or some such.  And the cliche (CATCH C (op C))
might well be packaged up into (SIGNAL op).  Or maybe PROVIDING and
REQUEST respectively.

-- Scott