Newsgroups: comp.object,comp.lang.eiffel,comp.lang.c++,comp.lang.beta,comp.lang.java,comp.lang.sather Path: news.daimi.aau.dk!news.uni-c.dk!newsfeed.sunet.se!news00.sunet.se!sunic!news99.sunet.se!nntp-trd.UNINETT.no!Norway.EU.net!oslonett.no!sn.no!newsfeed.tip.net!peroni.ita.tip.net!everest.vol.it!dsi.unimi.it!univ-lyon1.fr!jussieu.fr!math.ohio-state.edu!newsfeed.acns.nwu.edu!ftpbox!mothost!schbbs!news From: shang@corp.mot.com (David L. Shang) Subject: What Should An Exception Handling Do? Reply-To: shang@corp.mot.com Organization: MOTOROLA Date: Thu, 14 Mar 1996 15:56:41 GMT Message-ID: <1996Mar14.155641.4299@schbbs.mot.com> Sender: news@schbbs.mot.com (SCHBBS News Account) Nntp-Posting-Host: 129.188.128.126 Lines: 136 Xref: news.daimi.aau.dk comp.object:52688 comp.lang.eiffel:22344 comp.lang.c++:173455 comp.lang.beta:10661 comp.lang.java:26227 comp.lang.sather:12347 I cross post this message to languages that have exception handling, and am asking for better ideas in exception handling. I like Ole Madsen's definition in his book: An exception is a class of computational states that requires an extraordinary computation. It is not possible to classify whether state is expected or not; but this state do need some extraordinary attention. We have two cases: 1. Such extraordinary attention required in a function is dependent on the user's choice, and an implementor can do nothing with it; 2. Such extraordinary attention can be handled by the implementor directly; I belive that the first case is the most important; and the second case does not necessarily to use exception handling. And the first case is rather easy to be handled for recovery. But, most exception handling mechanisms focus on the second case, which makes exception handling very complicated for recovery. (C++ even gives up recovery.) Also, exception handling helps in improving the code readability in the first case, but may unecessarily complicate the code structure in the secon case. Let us consider a simple example: a function to put an item in a collection. We consider the second case first. Suppose that the put function should expand when a full "exception" is raised. The implemetor will expand the collection without allowing the user's decision. If we use exception handling, the code will read like this (not in any language): class collection { function put (item: any) { if (full) throw COLLECTION_FULL; // raise an exception put the item in } catch // { when COLLECTION_FULL: expand(); retry; } } The code structure is unecessarily more complicated than: class collection { function put (item: any) { if (full) expand(); put the item in } } Now, we consider the second case: the put function should ask user's decision. Then exception is a good mechanism to handle this situition (in Transframe): class collection { function put (item: any) exception (COLLECTION_FULL) { if (full) throw COLLECTION_FULL; // raise an exception put the item in } } Now user should decide what to do: c: collection(); // create a collection; try (c.put("a_string")) { when COLLECTION_FULL: c.expand(); retry; }; This structure is more readable than the one in which exception handling is not used. Let us have a comparison on the useage of file's open operation. With exception handling, user can write code: f: file of Image(); // create a blank file reference; image: Image = try (f.open(name)) { when FILE_NOT_FOUND: if (name!=system_name) name:=system_name; else name:= my_window.PopupOpenFileDialog(); if (name) retry; else return null; when FILE_WRONG_TYPE: name:= my_window.PopupOpenFileDialog(); if (name) retry; else return null; }; Without expcetion handling, user has to write code like: f: file of Image(); // create a blank file reference; image: Image; err_info: FileErrorInfo; image = f.open(name); while (!image) { err_info:= f.GetFileErrorInfo(); switch (err_info) { case FILE_NOT_FOUND: if (name!=system_name) name:=system_name; else name:= my_window.PopupOpenFileDialog(); if (name) image = f.open(name);; break; case FILE_WRONG_TYPE: name:= my_window.PopupOpenFileDialog(); if (name) image = f.open(name); break; } if (!name) break }; Lots of flow-control statements are involved, and the structure of the code becomes complicated, error-prone, and unreadable. David Shang