Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!mcsun!ukc!pyrltd!tetrauk!rick From: rick@tetrauk.UUCP (Rick Jones) Newsgroups: comp.lang.eiffel Subject: Re: Exceptions and Assertions Keywords: eiffel exceptions assertions preconditions Message-ID: <731@tetrauk.UUCP> Date: 11 Sep 90 09:35:15 GMT References: <1990Sep7.032121.6456@bony1.uucp> <14831@yunexus.YorkU.CA> Reply-To: rick@tetrauk.UUCP (Rick Jones) Organization: Tetra Ltd., Maidenhead, UK Lines: 116 >Speaking of exceptions, I wrote: >| One of Eiffel's most powerful features is its exception handling, and in my >| current work I am experimenting with a programming style which places heavy >| reliance on this system. The general concept is that _all_ "non-normal" >| conditions are treated as exceptions, including those which may be expected to >| occur quite frequently. > >richieb@bony1.uucp (Richard Bielak) writes: >| IMHO, pushing non-normal cases into exception handlers is wrong. An >| exception should only be used to handle the cases that were not >| foreseen by the developer. Doing a "raise" and handling a condition >| elsewhere in the program has two problems: > >| 1) Flow of the code is hidden from the programmer reading the code; a >| "raise" is almost as bad as a GOTO. On the other hand, code which has to handle all the non-normal conditions in-line also hides its flow. Trying to find the salient thread among all the actions dealing with the unexpected can be a real problem. The advantage of exceptions is that the routine which detects the problem may be several nested layers removed from the routine which is capable of dealing sensibly with it. Without exceptions the intermediate code has to know about the error conditions simply to pass them back to the previous level. I look at exceptions as "structured goto's", and I don't think that makes them bad per-se. I know the NO-GOTO syndrome is a religion with some people, but every construct can be valuable in the right place. Basically, GOTO's can be good as a way OUT, it's if you use them as a way IN that you get into trouble. >| 2) If too much code is put in an exception handler, what will happen >| if the handler encounters an exception? I agree here, exception handlers should be simple. But Eiffel's "retry" concept means that the exception handler (rescue clause) simply flags that an exception has occurred, and the main procedure checks this flag. The "real" code which progresses the application following an exception is an alternative route through the procedure body. This is a unique (I think!) feature of Eiffel's exception mechanism. >| [paraphrased]: should Eiffel programs generally be run with pre-condition >| checking on? - yes! yes! yes! I am coming round more and more to this point of view. I have done a few more experiments on compilation options, and the overhead of running with pre-condition checks on in the current implementation seems to more associated with exception history tracing than with the assertion checks. This is because every routine gets a default rescue clause even if there is no explicit one. This only disappears when the "no-assertion-check" compile option is used. The most effective run-time (i.e. C compile-time) option would be to check pre-conditions, void references, "check" clauses (my preference), but omit history tracing. This means that spurious setjmp() calls are avoided, and a longjmp() in the case of an exception will go direct to the currently effective rescue handler. This all seems possible with a little re-arrangement of the _eiffel.h file; any comments from ISE, please? davecb@yunexus.YorkU.CA (David Collier-Brown) writes: > We're really seeing a continuum here: the normal case, the general case >and the exceptional case. > > In the normal or common case, one wants to pass through a concise, >understandable sequence of code. Often one wants this to be fast, in >some sense of the word. > In the general case, one has to deal with the boundary conditions, >special oddities, etc, or the algorithm. > ... > In the exceptional case, on has to deal with "can't happen" events. I think this is fair comment. It's clear that conventional code is for the normal case, and exception handlers are for the exception case. The question seems to be, where does the general case belong? Should the language have a method for handling these conditions distinct from the other 2 cases? If not (which is the current reality), I think it depends on the particular application. As I said, my application is transaction processing, and the general style here is that an inability to complete the transaction requires the entire transaction to be aborted. The transaction manager is external to Eiffel, and its ABORT routine is in effect an exception handler since it will throw away everything done so far and return to its caller. There seems to be some merit in defining an Eiffel rescue clause at the same level as the transaction start point whose job is to invoke the ABORT routine. Hence any inability to complete the transaction which may result from conditions only encountered at some depth of routine calls can just raise an exception and forget the problem. However, this may not be an appropriate style for all applications. In many programs the general case may well be better handled in-line. On this topic, I have just read the descriptions of the proposed C++ exception handler in the latest issue of JOOP. While it is far more limited than Eiffel's exception handler, it does raise (?!?) some interesting points. a. It argues that program clarity is _improved_ if exceptions are used to handle the abnormal, which includes "expected errors" such as open-file errors. This is in line with my arguments above. b. It provides a powerful means for the programmer to distinguish his own exceptions, since an object of a programmer-defined class is passed from the the exception point to the handler. I think this second issue is a major problem in Eiffel, since there is only one "programmer exception" type, and the only information which can be defined is a string. Assertions of course allow labels, but that comes to the same thing. This is fine if you just want to print out the exception to the user, but if an exception handler needs to do any serious analysis of the exception for the purpose of alternative recovery strategies this is very difficult to do in a structured manner. Could Eiffel's exception mechanism be extended to allow more arbitrary information to be passed to a rescue clause? -- Rick Jones Nothing ever happens, nothing happens at all Tetra Ltd. The needle returns to the start of the song Maidenhead, Berks, UK And we all sing along like before rick@tetrauk.uucp - Del Amitri