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

Issue: UNWIND-PROTECT-CLEANUP-NON-LOCAL-EXIT (Version 2)



I don't see why the "is an error" possibility for case one has been
discarded out of hand.  The only argument for making this well defined
is that it is "in the way of producing a valid portable error system".

One could suppose that there are complex, non-obvious, situations in
which one of RETURN-INNER or RETURN-OUTER is required to implement an
error system.  If this were the case, then we would be forced to make
that choice.  But Moon (I believe) argues that it is quite acceptable
to be required to signal an error, and thus SIGNAL-ERROR is presumably
not incompatible with having a portable error system.

Moon further went on to argue that the error which is required to be
signalled is required not to be handleable.

This seems to be a strong indication that "is an error" is in fact the
correct interpretation.  The language semantics of "an error that
cannot be handled" is indistinguishable from "is an error", since a
program cannot exploit this distinction.  This is a pure environment
issue.

Of course, saying that this condition "is an error" allows all of the
suggested interpretations, and thus means that noone is required to to
anything.

My presonal preference for a definite semantics of this construct is
RETURN-INNER.  This is largely due to the conceptual simplicity that I
as a compiler writer perceive.  The reason I have argued for "is an
error" is that I don't want to be forced to implement any of the
alternatives.  

I think that people have greatly underestimated the semantic garbage
that this change will load on to lexical exits.  The reason that this
doesn't bother anyone is that existing Common Lisp implementations
implement non-local lexical exits on top of dynamic exits, rather than
the other way around.  It is bogus to suppose that each syntactically
distinct BLOCK will have a distinct run-time data structure that you
can allocte bits in.

If you have a construct like:
  (block foo
    ...
    (block bar
      ...))

It is not currently required that compilers maintain any distinction
between blocks FOO and BAR; those are just different names for the
same continuation.

Yet if we fill in the ...'s in this way, then SIGNAL-ERROR prevents
the obvious interpretation of BLOCK as naming a continuation:

  (block foo
    (block bar
      (unwind-protect
          (return-from foo 'foo)
	(return-from bar 'bar))))

FOO and BAR name exactly the same continuation, but they are somehow
magically gratuitously distinctified simply due to being used from
within an unwind-protect.

Note that in this test case, the result of RETURN-INNER and
RETURN-OUTER are exactly the same.  Although I favor RETURN-INNER,
RETURN-OUTER is not nearly as semantically bankrupt as SIGNAL-ERROR,
since it doesn't require distinctions to be made between identical
continuations.  

But I still believe RETURN-OUTER is more difficult to implement than
RETURN-INNER, since it still introduces an innerness/outerness
distinction that is not fundamentally part of a lexical exit.  In
simply naming these proposals RETURN-INNER/RETURN-OUTER, a dynamic
component has implicitly been introduced into lexical exit.

RETURN-INNER simply ways "use this continuation"; RETURN-OUTER says
"maybe use some other continuation depending on some rule of dynamic
scoping that is otherwise totally irrelevant to the semantics of
RETURN-FROM unless there is an UNWIND-PROTECT around somewhere".

  Rob