Charlie Reitzel wrote: > I was quietly reading this thread, but I must respectfully but > strenuously disagree with the premise that exceptions are "simply > another kind of flow control". OK, semantically exceptions _are_ > another type of flow control. Let's not jump down a rathole. But, > in any language, exception-safe code is much harder to write than > most programmers realize.
I don't know how strenuous your disagreement is when we seem to agree about exceptions as flow-control. It sounds like you want to strenuously make a point about how this programming concept is non-trivial. I agree. I'd similarly agree that threads, objects and lots more are more complex than people might think. Programming is hard and requires knowing both the machine and the problem space. Of these, the machine space is the easier one. Everything (nigh-everything) is just math & flow control. And flow control is just test & goto. What makes programming hard are the attempts to model problem spaces and formulate languages and concepts appropriate to those models. When I said exceptions are just flow control, I meant it in the broad, almost-trivial machine sense. Any given language model can implement them in a way that makes it inappropriate to use them that way; but that's the basic idea as modeled by setjmp/longjmp. > If every method is re-entrant, there is nothing to worry about > because stack unwinding deals effectively with method-local state. > But as soon as methods start affecting the longer term running state > of a system, exceptions can easily leave that system in an > inconsistent, possibly broken state. This is why many languages provide TRY...FINALLY, eh? And others use lexically guaranteed destructors to the same end. That Perl provides neither is one of the flaws in its exception handling. > True, bad code can do all that without the "benefit" of exceptions. > But, even otherwise solid code can go horribly wrong because > exceptions are thrown in a 3rd party library. Non-throwing code is > much, much less likely to have that impact. One can make the same form of argument against using threads, objects, etc... Things can go horribly wrong in many ways for many reasons. One of the problems with the Perl "You can have exceptions if you want them" approach is similar to that of C's "Threads arrived later" -- lots of code assumes no one will be using exceptions/threads, so is not "safe" in the presence of those things being added. An advantage of the Java "We have threads & exceptions -- they may be implemented badly, but they're always there" approach is that all programmers are aware that those things are there, and they (if at all competent) make some plan to deal with it. (Typically badly, but safely.) > This is the reason why coding standards for systems with very high > uptime requirements often disallow throwing exceptions. This can > extend to disallowing use of libraries that throw (or taking pains > to configure libs so that they do not). This is one of those things which is pseudo-true. Obviously, neither using nor avoiding flow control is a guarantee of uptime. (Though perhaps not using flow control is a guarantee of minimal uptime.) What this policy is really saying (as I'd read it) is that, in an effort to avoid program defects, the program behavior should be kept as simple and obvious as possible. Which is fine. Until/unless you reach a point where it conflicts with another requirement, such as hard, real-time performance. Say you have code in a tight loop which has to call N functions, and if any of them returns X (which isn't considered an error), it has to return. Without exceptions, that means performing N tests. With exceptions, it requires no tests at all -- the functions themselves can simply throw 'X' when it happens. And before (or just after) you think it -- yes, that's a very vague example fraught with potential alternatives. But, it expresses a good use-case for fast, goto-like, not-just-for-errors exceptions. (Just to mention, an alternative, similarly efficient approach is to use continuations of some type and allow each function to decide between passing control to "keep-trying" or to "X-happened" alternatives.) > Put another way, the "rare" nature of Exceptions (go figure) is > implied in the sub-optimal treatment given by compiler writers to > exception code paths. You sure as heck don't want to optimize > Exceptions at the expense of the regular, non-Exception code paths! Slow exception implementations are suitable only for rare code-paths. But that does not mean that setjmp/longjmp are slow and can only be used rarely. You're somewhat inverting the cart and horse. Also, there is little or no tradeoff (this can depend on the CPU) for having exceptions present in a language -- but once you allow them at all; you have paid the penalty. (The penalty is related to "return" and "try...finally" -- essentially, every "return" must become equivalent to an exception, so it will hit the "finally" handlers properly. Or, similarly, so it will call destructors.) Once present, the speed of exceptions is only constrained by how much "stuff" one adds on top of the longjmp-or-equivalent implementation. For example, if every exception starts by tracing the stack & gathering debug information that can later be used in an error message.. that's going to be a little slow. A language can offer the programmer a choice of throwing "fast" or "slow" exceptions, depending on what they're used for. _______________________________________________ Boston-pm mailing list [email protected] http://mail.pm.org/mailman/listinfo/boston-pm

