Path: news.daimi.aau.dk!news.uni-c.dk!newsfeed.sunet.se!news00.sunet.se!sunic!mn6.swip.net!plug.news.pipex.net!pipex!tube.news.pipex.net!pipex!lade.news.pipex.net!pipex!tank.news.pipex.net!pipex!news.mathworks.com!newsfeed.internetmci.com!in1.uu.net!uunet.ca!news.uunet.ca!nobody Sender: nobody@banshee.uunet.ca X-Nntp-Posting-Host: nellie.cygnus.com Message-ID: <31647113.13BD8C66@cygnus.com> Date: Thu, 04 Apr 1996 20:02:11 -0500 From: Kim Knuttila X-Mailer: Mozilla 2.0 (X11; I; Linux 1.2.10 i586) MIME-Version: 1.0 Newsgroups: comp.object,comp.lang.eiffel,comp.lang.c++,comp.lang.beta,comp.lang.java,comp.lang.sather CC: krk@cygnus.com Subject: Re: What Should An Exception Handling Do? -- Clarification of rules References: <1996Mar25.160011.13921@schbbs.mot.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 247 Xref: news.daimi.aau.dk comp.object:53786 comp.lang.eiffel:22677 comp.lang.c++:176845 comp.lang.beta:10709 comp.lang.java:31616 comp.lang.sather:12417 [Aside: there's lots of newsgroups on the outbound line... I'll assume that all are fascinated :-)] David L. Shang wrote: > > In article bs@research.att.com (Bjarne Stroustrup > <9758-26353> 0112760) writes: > > billf@jovial.com (Bill Foote) writes > > > > > > > > quote explaining why C++ (and Java) uses the termination model > > > > of exception handling > > > > > > A cynic might conclude something more along these lines: "It would be > > > hard to implement resumable exceptions in C++, so they decided to punt." > > > > and that "cynic" would be wrong, guilty of not having done his homework, > > and guilty of making unkind conjectures without basis in facts. > > > > But I don't see what's wrong with the cynic. It is true that to > implement resumable exceptions in C++ is very hard. It is also > true that resumable exception is useful, see below. > Hmm.. Well, it depends if you're interested in accuracy or not. If you want to believe that the committee did something for some reason, feel free to. For many things it may not even be totally incorrect. There are lots of people voting for lots of reasons. There were probably some votes that would agree with the cynic! (i.e. didn't want the implementation grief.) But in this case, I don't believe the majority did. For what it's worth, I don't think the degree of difficulty of implementation was a big issue. Most implementors present had experience with building EH type systems in other languages. In the debates (over a couple of years!), implementation strategies were scoped out, and the relative merits were discussed (I loved this part! :-). I believe most folk, at least the direct participants in the extension work group, understood where resumption could be useful, as opposed to termination. After all, EH is not really a "new" thing, right? In the end, it boiled down to philosophy of language design and the fact that C++ is OO, not procedural. Perceived costs, perceived values, peoples experience, etc. The entire discussion was very, very long, and very, very detailed. (I'm leaving out reams of interesting, germane stuff. My notes are packed and I can't exactly get at them. Actually, I'm probably optimistic in thinking I'll ever find them. If there's interest, I'll rummage after my move) And reasonable, intelligent people had differing opinions. Concensus was arrived at eventually, but it took a lot of pretty thorough discussion. > > Here, I'd like to quote a key section: > > > > Then, at the Palo Alto meeting in November 1991, we heard a > > brilliant summary of the arguments for termination semantics > > backed with both personal experience and data from Jim Mitchell > > (from Sun, formerly from Xerox PARC). Jim had used exception > > handling in half a dozen languages over a period of 20 years > > and was an early proponent of resumption semantics as one of > > the main designers and implementers of Xerox's Cedar/Mesa system. > > His message was > > > > ``termination is preferred over resumption; this is > > not a matter of opinion but a matter of years of > > experience. Resumption is seductive, but not valid.'' > > > > He backed this statement with experience from several operating > > systems. The key example was Cedar/Mesa: It was written by people > > who liked and used resumption, but after ten years of use, there > > was only one use of resumption left in the half million line > > system -- and that was a context inquiry. Because resumption > > wasn't actually necessary for such a context inquiry, they removed > > it and found a significant speed increase in that part of the > > system. In each and every case where resumption had been used > > it had -- over the ten years -- become a problem and a more > > appropriate design had replaced it. Basically, every use of > > resumption had represented a failure to keep separate levels > > of abstraction disjoint > > This summary understandably doesn't really do justice. Jim Mitchell was extremely interesting. I believe he spoke for an hour or so, and then fielded questions on the work he's done, opinions held, etc. The body of work, the size and scale of it... it was just very very interesting. > > Mary Fontana presented similar data from the TI Explorer system > > where resumption was found to be used for debugging only, Aron > > Insinga presented evidence of the very limited and nonessential > > use of resumption in DEC's VMS, and Kim Knuttilla related exactly > > the same story as Jim Mitchell for two large and long-lived > > projects inside IBM. To this we added a strong opinion in favor > > of termination based on experience at L.M.Ericsson relayed to > > us by Dag Bruck. > > > > Thus, the C++ committee endorsed termination semantics. > > > > The key point is: WHAT IS AN EXCEPTION? > Precisely. And the sister assumptions regarding frequency of use, (throw/catch infrequent relative to function calls, for example) and that kind of stuff to guide implementors on efficient implementations. And the other ones: when you are in a catch handler, is the stack unwound or not? (i.e. have the destructors run?) Who decides? When? What assumptions can be made at the throw point? Note that these are not unsolvable. In fact, quite the contrary. The termination model is almost a perfect subset of the resumption model. And the simplicity of it (not from the implementation point of view) did have some appeal. (i.e. some folks like that part in particular) The full model gets pretty elaborate, but it's definitely implementable in plausible time. (We implementors like job protection :-) > The definition: > > > "Exception handling is intended to allow code that has encountered > >a condition it cannot cope with to return to some other code that > >directly or indirectly invoked it. There is no way for an exception > >handler to request the thread of control to resume from the throw point. > >In other words, "throw" implements the termination model of exception > >handling." -ARM, Ellis & Stroustrup, page 354 > > > > narrows exceptions to error conditions only. If it is this case > termination would be sufficient, and resumptions would be useless. > And I think you've hit the nail on the head, so to speak. The committee endorsed the ARM model of exceptions. (i.e. errors) Of course, we all know that if you adopt a different paradigm (damn, I swore off that word) that you can view exception handling as "just another control flow mechanism." In fact, in the evenings (we don't get out much) some entertainment was derived from "inventive use of resumption" coding examples. Goto's were mundane in comparison. So I doubt that many would argue that there exist problems whose solution is elegantly expressed in the terminolgy of resumptive exception handling. (the favorite example in the "pro" camp was "the diskette drive is not ready") There may be more arguments over the number of such problems, and whether the resumptive solution is the only elegant solution or just someone's favorite paradigm. But the major point is, as you point out, once you decide on the definition of "exception", much of the rest falls out. > But an exception is not necessarily an error. Sometimes it is an > condition that requires some extraordinary computation, a condition > that is not supposed for a regular case, for example, to open a > configuration file in an application directory and the file is not > found. This condition requires a further processing, e.g. to look up > the file in system directory. This is a quite common case in every > system design. More examples: > > * the font does not exist and a query to the user is required to > get the substituting font; > * the input is in the wrong type and an input retry is required; > * the file is not associated with a default handler, would you > like to associate one and let me try to re-open the file? > * the format is not understood, would you suggest me a > converter? > * the embedded object is re-located, would give me the directory > to the new place? > > These conditions are not errors but only require some extraordinary work. > Similar examples were also given by Bill Foote in his previous post. I didn't see Bill's post (It's been a while since I've had time to read. I probably still don't have time :-), but if someone kept it...? > It is not hard for people to figure out more examples that requires the > following struture: > > result = try do_something() > { > when condition1: some_extraordinary_work1; retry; > when condition2: some_extraordinary_work2; retry; > when condition3: some_extraordinary_work3; retry; > when condition4: return null; > } > It's hard to make generalizations (I'll certainly be wrong on this one), but the design issue is deciding who has what responsibility, and if you want to abdicate responsibility, what's the best way to do so. A great many can be solved by reviewing the object/responsibility relationships that got us here. (Wow, that's a RealGeneralization(tm)) Somehow this feels like seeing OO code with lots of switch statements in it. It's not that "switch" is never used anymore. It's just that it's pretty infrequent in the stuff I've worked on in the past, so the occurrence was usually pretty special. > is certainly better than: > > result = do_something(); > exceptional_condition = check_error_message(); > while (exceptional_condition) > { > if (exceptional_condition==condition4) > { > result = null; > break; > } > switch (exceptional_condition) > { > case condition1: > some_extraordinary_work1; > do_something(); > break; > case condition2: > some_extraordinary_work2; > do_something(); > break; > case condition3: > some_extraordinary_work3; > do_something(); > break; > } > } > > Oh, well! It takes me ten time longer to figure out the second piece of > code and I am still not sure whether this code is correct or not. After > a second look, yes, there are errors! "check_error_message()" should also > be called in the loop to get the new exceptional condition after a retry. Yep. You could try recursion for some of these types of problems too. But it's still the case that if you really, really have a problem that can only be solved elegantly using resumption, then you'll be doing something like this. > > David Shang -- Regards, krk. Kim Knuttila | Do I need to say it? well alright... Cygnus Support | I don't Speak for Cygnus, They don't Speak for me. Toronto, Ontario | I don't even Speak for Jake.... bus: krk@cygnus.com | But I do speak for myself... Woof.