On Dec 3, 2003, at 12:03 PM, Dan Sugalski wrote:

At 12:17 PM +0100 12/3/03, Leopold Toetsch wrote:
Dan Sugalski <[EMAIL PROTECTED]> wrote:

> *) Exceptions we're happy with

Create an Exception class hierarchy?

I'm not 100% sure I want to go with a real OO style of exceptions, but that might just be the neo-luddite in me.

I'm of the opinion that it's a conceptual mistake to model exceptions as objects. My main concrete argument is that it's an abuse of inheritance--you need a hierarchy of exception reasons, but using inheritance just to get a hierarchy is silly. (That is, it doesn't make sense to subclass if you are not changing behavior in some way.) In addition, I think it's overly restrictive.


Fundamentally, I think raising an exception requires two things: (1) some indication of "reason" for the exception (used by the exception infrastructure to select the correct handler), and (2) a way for the originator of the exception to pass some arbitrary information to the handler (this information being opaque to the exception infrastructure).

In C terms, that would mean that the signature is conceptually like:

raise_exception(Reason reason, void* info);

which in Parrot terms would probably shake down to:

raise_exception(Reason reason, PMC* info);

The "Reason" data type could either be a structured string, such as "parrot.io.staleFileHandle", or some sort of array of strings--just enough to indicate a hierarchy to be used for selecting a handler.

The key point here is that the "reason" parameter is what is needed by the exception infrastructure to choose the correct handler (and to decide what to do if no handler is found), and "info" just has to be of a form agreed upon by the "thrower" and the "catcher".

This sort of approach would work with languages such as Java which expect exceptions to be objects--in this case, the Java exception object would be passed as the "info", and the "reason" would be derived from the type of that object.

For simpler languages (and possibly even for Perl6), "info" could just be a hash--no real need for a specialized type of object.

I think the core of my thinking here is that exceptions don't really have behavior--at most they are a bag of data (which is what hashes are usually good for), and really they are a process for jumping the flow of execution, and sending along a bag of data to indicate why it just happened.

That was a bit long-winded, but basically I'm saying that I'd like to see the pasm for raising an exception take the form:

raise Px, .parrot.io.StaleFileHandle

where Px may actually be null.

No matter what approach we take, we're going to have issues throwing exceptions across language boundaries (ie, Perl exception handled by Python code), since different languages aren't going to agree on how to classify exceptions--and having exceptions be HLL objects seems to make this worse. Actually, in a sense this _might_ not be a problem: If we supply a decent reason hierarchy, then using our supplied parrot.* exception "reasons" would allow an exception thrown in one language to be handled in another; if a language-specific reason is used (e.g., perl.blah), then it's probably going to only end up being handled by code in the same language. (And that seems fine--even in Java if I create my own Exception subclass, then code I haven't written isn't expected to be catching that type of exception.) But having some standard types will make it possible to cross language boundaries meaningfully.

Just some thoughts.

One other thing: Long-term, it would be good to avoid having an exception handler stack which we push and pop as we do now, and instead use a variant of the zero-overhead approach used by C++ (and probably Java), wherein try-catch blocks incur zero execution overhead--CPU time is only consumed when an exception is actually thrown, and not when a "try" block is entered or exited.

JEff

Reply via email to