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

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



Ok, I've caught up on my reading on this one...

    Date: Tue, 24 May 88 03:00:59 PDT
    From: Jon L White <edsel!jonl@labrea.stanford.edu>

    ...
    The operative phrase we have come up with is that

	THROW "commits"

    That is, when a THROW decides that there is a catch-tag somewhere up
    there to catch it, then no intervening UNWIND-PROTECT can function like
    a catch barrier.
    ...

I just don't believe any of this. You can say "THROW commits", I can say
it doesn't.  You assert it as if it were true and then try to derive a
semantics based on that unsupported presupposition. We all agree that
THROW commits to the extent that it chooses where it wants to unwind to.
What we don't agree on is whether it is well-defined, is an error, or
signals an error if you try to keep THROW from doing what it had set out
to do.

On a recent invitation to a marriage ceremony, I was asked to say (in addition
to whether I'd be attending) what my definition of "commitment" was. I thought
about this a long while and finally decided that the word is misleading and
that I would attack its usage as an absolute. One does not commit in the absolute,
one commits relatively. It's meaningless to say "I'm absolutely committed to
this person" or "I'm absolutely committed to this project" because (as Steele
points out in the Discussion section for this issue) you immediately run into
problems of conflicting absolutes (irresistable forces and immovable mountains)
When making a statement of commitment, you must say what your priorities are,
relative to other things which might come into conflict.

Consider the case of

 (DOTIMES (I (* A B)) ...)

Certainly we must say that this DOTIMES "commits" to doing some number of
iterations, but all that means is that it has decided it's going to do that
and no modification of A or B is going to change that. But it doesn't mean that
something can't come along to shake it free -- its level of commitment is low.
It should not be said that this loop is a "failure" if a RETURN is executed.
Rather, we should just identify that its initial level of commitment to executing
all A*B steps is lower than its commitment to stopping the loop if a RETURN is
executed.

Ditto for THROW. I'm happy to say "THROW commits". I'm just not happy to say that
there is nothing in the language which might not have higher priority. Further,
but independently, I personally wish that another THROW should have such higher
priority.

    What's not OK is to block a "committed" THROW.  Without this restriction,
    for example, an "abort" to top-level while runnining the application
    evaluator noted below would never succeed; the THROW to FOO from within
    the cleanup form would serve as an effect barrier such that no throw can
    go past it.

	  (loop
	    (catch 'foo
	      (unwind-protect 
		    (Run-application-evaluator)
		(throw 'foo t))))

That's right! It WOULD serve as a barrier that no one can go past. But
did it occur to you that someone might want that? People have pulled a
lot of wild cases out of the air, but the only non-contrived situation
we have in this entire conversation is the one that I brought in from
Macsyma when I introduced this situation. I wanted to make a new
toplevel on top of Lisp's so that I could not get back to Lisp. I wrote
just the piece of code that you see above (except
RUN-APPLICATION-EVALUATOR was called something like MACSYMA-TOPLEVEL)
with certain expectations that you are claiming would not be wanted, and
yet I know for a fact that they are exactly what are wanted.  Can you
cite any other real world examples of anyone getting involved in this?

I agree with Walter that the issue of an "unstoppable" loop is so much
bigger than this problem that we just shouldn't get involved in that
here. Every implementation should provide a way to unwind the stack
without running the unwind protects and everyone's debugger should offer
an interactive entry point to that mechanism for cases where you get
wedged and need to stop a program. Beyond that, I don't see that more is
required.

I think GLS says it best in the discussion on the proposal as currently
written:
 ``Which mechanism are to we regard as primitive: the error system or the
   catch/throw system?  Or are they disjoint?  I prefer, for simplicity, a
   model in which the error system can be explained. as much as possible,
   as a complex thing built on top of catch, throw, and unwind-protect.''
I shudder to think about a system whose control semantics must appeal to the
condition system. I side with GLS in preferring to think of the error
system as a user program layered atop a simple set of control primitives.

I [still] support UNWIND-PROTECT-CLEANUP-NON-LOCAL-EXIT:CONTINUATION-MODEL
(now version 4).

Having been the self-righteous underdog in some of these other battles,
I'm very concerned about not seeing legitimate points of views stifled.
Remarks by Moon and JonL should be duly noted at least in the discussion
and, if they desire, as a competing proposal. It's clear we're not going
to get closure within this group since we have no voting authority. Let's
take it to the full community.