Path: news.daimi.aau.dk!news.uni-c.dk!newsfeed.sunet.se!news00.sunet.se!sunic!news99.sunet.se!columba.udac.uu.se!news.mdh.se!news.seinf.abb.se!erinews.ericsson.se!cnn.exu.ericsson.se!newshost.convex.com!news.duke.edu!news.mathworks.com!tank.news.pipex.net!pipex!dispatch.news.demon.net!demon!sunsite.doc.ic.ac.uk!yama.mcc.ac.uk!news.salford.ac.uk!aber!not-for-mail From: pcg@aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.object,comp.lang.eiffel,comp.lang.c++,comp.lang.beta,comp.lang.java,comp.lang.sather Subject: Re: What Should An Exception Handling Do? -- Clarification of rules Date: 31 Mar 1996 23:05:34 +0100 Organization: Prifysgol Cymru, Aberystwyth Lines: 100 Sender: pcg@osfb.aber.ac.uk Message-ID: References: <4irn11$7ln@mimas.brunel.ac.uk> <4j03p4$fbt@hoho.quake.net> Reply-To: pcg@aber.ac.uk (Piercarlo Grandi) NNTP-Posting-Host: osfb.aber.ac.uk In-reply-to: bs@research.att.com's message of Sat, 23 Mar 1996 13:50:55 GMT X-Newsreader: Gnus v5.0.15 Xref: news.daimi.aau.dk comp.object:53593 comp.lang.eiffel:22629 comp.lang.c++:176219 comp.lang.beta:10699 comp.lang.java:30648 comp.lang.sather:12385 >>> On Sat, 23 Mar 1996 13:50:55 GMT, bs@research.att.com (Bjarne >>> Stroustrup <9758-26353> 0112760) said: bs> billf@jovial.com (Bill Foote) writes billf> It's not too hard to come up with examples where it would be nice billf> to have resumable exceptions. One example is resource billf> acquisition. Upon failure to acquire a resource (a file billf> descriptor, some memory, etc.) it might be nice if a top-level billf> exception handler could try to free up some resources, and if it billf> can, try to resume from the exception. Uh, but that's not an exception: that's more or less speculative execution. More on this point later. bs> This point, and many others were seriously studied by the C++ standards bs> committee before it approved my design of exception handling for C++. bs> The arguments for and against resumption can be found in chapter 16 of bs> Bjarne Stroustrup: bs> The Design and Evolution of C++ bs> Addison-Wesley ISBN 0-201-54330-3 bs> together with a description of the complete language features and examples bs> of their use. bs> Here, I'd like to quote a key section: bs> [ ... a lot of experience shows that most language implementors find bs> out, often to their surprise, that termination is almost universally bs> cleaner and preferred). Actually, let me add the Ultimate Truth about exception, to support this, not just experience; exceptions are a widely misunderstood concept, often commingled with interrupts and other unrelated subjects (in some cases exceptions have been considered even *values*). Let's tart from the beginning: a program/module/function that implements a total function cannot possibly have exceptions; conversely an exception can only arise when a program/module/function does not implement a total function. An exception happens when a bit of code implementing a partial function is fed data outside the codomain of the total function. Using Dijkstra's if-fi, an exception happens *iff* the data do not satisfy the precondition of an if-fi construct somewhere; for example: float sqrt(float n) { if n > 0 -> ... [] n == 0 -> return 0; fi } A code segment may implement a partial function for one of just two reasons: * the function is *intrinsically* partial, in which case its application to the given data is in error, and thus execution must terminate. * the function is not necessarily partial, but there are several conceivable alternatives on how to make it total, and the author of the code segment does not want to force a particular definition on the use of the function. It is *only* in the latter case that exception handling makes any sense, more or less obviously. An example might be assigning a meaning to 'operator /' when the operands are zero: should '0/0' be 1? An error? Infinity? All these are legitimate choices, that should not be preempted. Therefore exception handling reduces to simply providing a mechanism by which the *author* of a code segment provides a mechanism by which the *user* of that code segment can specify additional cases, as for example in: float sqrt(float n) { if n > 0 -> ...; [] n == 0 -> return 0; [] n < 0 -> return sqrt_negative(n); fi } where the only difficulty is that sqrt_negative must be dynamically scoped instead of statically scoped, for it must be redefinable by the *user* of the procedure. This again means that termination is the only possible outcome for this case too. The exception facility of e.g. C++ is merely a (rather ad-hoc and opaque) way of allowing the definition of what are in effect dynamically scoped procedure names, forcibly coupled with non-local control transfer.