On Fri, Jun 16, 2006 at 10:51:24PM -0500, John M. Dlugosz wrote:
: Anyway, as passionate as I was about resumption, or at least making it 
: not impossible to implement resumption, at the next ANSI meeting the 
: terminate-only camp made compelling arguments. 

Well, interestingly, I used to be in the terminate-only camp.

: I don't remember what the "killer" argument was.  But I do remember bits 
: and pieces:  people with real-world experience on systems that have 
: resumable exceptions in some form ended up never using them; it 
: complicates the implementation; it is not necessary since callbacks fill 
: that role already (e.g. new_handler instead of resuming from the 
: bad_alloc exception); and the semantic concepts of what an exception 
: means.  To elaborate, the code throws when it can't deal with the 
: situation.  What does it mean if the throw worked like a function call 
: and returned?

In general, it would simply mean that you called warn() instead
of fail().  If you call warn() you're expecting to gamely attempt
to continue.  If you call fail(), you're not expecting to return.
Warning is all about expressing misgivings when you're not sure.
If we throw a warning like we throw an exception, then someone in
the dynamic context may well be more sure than we are whether the
warning should be suppressed or fatalized.

: Code would have to watch out for that, which defeats the 
: point of making the exception a clean get-away.  Really, after fixing 
: something the function has to start over at the top; e.g. try allocating 
: again... that's what a loop around the whole try/catch does, and is 
: today common practice! 
: 
: So on providing different places to jump to depending on whether the 
: exception is "fixed" or "not fixed", how is that different from a normal 
: catch block which can re-throw or drop out?

It doesn't give the code in question the option of raising objections
without giving up.  How would you like it if the only way you could
complain to your management was by turning in a letter of resignation
and hoping they'll rehire you immediately?  Instead, we use office
memos/email that can convey either warnings or resignations.

: Consider the error upon trying to open a file.  If the open command 
: contains a callback handler as part of itself, it can try again and 
: eventually return, transparantly to the caller who just sees that the 
: file was (eventually) opened.  But what if the caller needs to back up 
: and repeat some steps because of that failure, to get another running 
: start at the command so to speak?  That's what you can do with a 
: mechanism more elaborate than the callback built into the command.  But 
: you can do that with a try/catch now, having termination semantics, 
: already.  Besides syntactic sugar, how is resuming different from that?

Sure, and that's what fatal exceptions are good for.  If you are giving
up, throwing a terminate-only exception is exactly what you want to do.

But look at this from the other direction--how do we unify warnings
with exceptions such that people aren't forced to invent out-of-band
warning systems that duplicate most of what throwing exceptions
already does?

In a sense, the whole idea of "resumably exception" is looking at
it sideways from what you really want.  An exception is just some
bad news that you're trying to pass up the dynamic stack to get more
direction on.  Even if you don't define resumably exceptions at all, in
a language where continuations are first class objects, the *throwing*
code can install one of those into any exception that can hold one,
and bang, you've got resumable exceptions whether you want them or not.

The point you made earlier is one that I agree with, which is that the
*user* interface has to be clear at the point of the throw.  You don't
want to define your interface so that fail() ever returns.  It's like
a return: it documents that the following statement is not reached.
But we can treat warn() as a variant that does document the fact that
it installs a resume continuation, and then attempts to throw a kind of
exception that will be resumed by default.

We could go as far as to have another variant, despair() or some such,
that throws a resumable exception that is not expected to resume
by default, but someone in the dynamic scope might call our resume
continuation anyway.  So that function call would document that we
*probably* won't resume here but don't count on it.  If we do resume,
we'll still try to carry on somehow.

Note also that this cleans up the "local $SIG{__WARN__}" mess of Perl 5.
Perl 5 compartmentalized warnings from exceptions, but we're just not
gonna do that anymore.  It makes much more sense to unify them, I think.

The latest version of S04 documents how all this is expected to work,
in particular the notion that warnings are just considered control
exceptions so that they bypass most CATCH blocks but can be managed
via CONTROL blocks.

Larry

Reply via email to