| 1 | > This page documents my (Austin) response to a [http://irclog.perlgeek.de/parrot/2010-02-22#i_2018722 request] from Tene to complain [http://irclog.perlgeek.de/parrot/2010-02-21#i_2018057 more] about exceptions. This is like a "super TT#" in that maybe a bunch of change orders come out of it. (Maybe 0, too.) So other folks please, ''please'' chime in with stuff you know, or opine, about how exceptions ought to work. |
| 2 | |
| 3 | > --Austin |
| 4 | ---- |
| 5 | |
| 6 | The point of exceptions is to enable a whole bunch of 'dynamic' (like scope) flow control. |
| 7 | |
| 8 | = 'Typed' exceptions = |
| 9 | |
| 10 | The PCT stuff uses exceptions for things like return, break, and continue, as well as the conventional "a surprising result has occurred." |
| 11 | |
| 12 | There is a legitimate need for fast, static handling of different types of control transfers. Typed exceptions definitely are one answer to that need. |
| 13 | |
| 14 | It is conceivable that more types could be added. |
| 15 | |
| 16 | = 'Classed' exceptions = |
| 17 | |
| 18 | Most programming languages support the idea of exception classes. Further, they support catching exceptions based on a class hierarchy: catch an exception of such-and-such class, or any subclass. |
| 19 | |
| 20 | An exception class will likely extend a more basic exception class in the language. It is easily conceivable that exceptions may be implemented as roles, or using multiple inheritance. |
| 21 | |
| 22 | = Requirements = |
| 23 | |
| 24 | The current typed system fails to handle this approach. It is unlikely that a single-type-per-exception approach will ever perform adequately in the presence of multiple inheritance and role mixins. |
| 25 | |
| 26 | However, the current system is arguably fast - I have no data for this, but if it isn't fast then it has no redeeming value. A single numeric lookup deserves to be fast. |
| 27 | |
| 28 | I think the priority has to be given to making 'simple things simple.' For exceptions, that means performance for the control flow exceptions, and reliability for `die`. |
| 29 | |
| 30 | Performance, in this case, can mean whatever the internals guys want it to mean. But in general it should probably mean low cost and getting rid of nested interpreters. |
| 31 | |
| 32 | Implementation of 'unusual exceptions' should be optimized not so much for speed, but for convenience. That is, getting rid of inferior runloops, or whatever other thing raises its head. |
| 33 | |
| 34 | == Requirements == |
| 35 | |
| 36 | * The non-local flow, catchable exceptions, and fatal error mechanisms must be extensible - more different kinds of each may be added by user code. |
| 37 | * Non-local control flow needs to be fast, for things like 'break', 'continue', 'return' |
| 38 | * Handling of 'errors' needs to be reliable - no matter how bad the user code, a 'die' type error has to be '''delivered'''. |
| 39 | * Catchable exceptions should be handled well, but may trade performance for implementation facility. |
| 40 | |
| 41 | = Design Issues = |
| 42 | |
| 43 | A cloud over much of this is coroutines. Coroutines, or some other form of random flow, have to support separate "stacks" for control transfer. That is, if a lexical block throws a "loop break" control exception, the right outer block has to receive it. I suspect this may have already been thought through - I certainly hope so. |
| 44 | |
| 45 | That aside, control flow exceptions seem like they are really a different animal, piggy-backing on the exception mechanism. That's not wrong, per se, but it may be possible for control flow stuff to move to a different subsystem with better performance. |
| 46 | |
| 47 | In particular, control flow is generally "symmetric" - that is, you don't generate a "next" without knowing there's a "for" somewhere to catch it. (In fact, I suspect most languages know ''where'' the for loop is, to boot. Does a control flow implicitly have a target?) In this regard, control flow is probably more like 'longjmp' than the rest of the exceptions mechanism - you know where you're going, and there's a good protocol defined between sender and receiver. |
| 48 | |
| 49 | Presently, the throw internals are oriented towards a "nested call" instead of towards the "return the address of the next opcode". There are probably reasons for this, but are they good enough? |
| 50 | |
| 51 | There has been some pressure to "make exception handlers be subs" (TT#1091), and the counter-pressure was the handling of control exceptions. If there is validity to the runloop problems being tied to continuations (vice subs), this would be a good opportunity for a split. |