19

I'm familiar with a dozen of programming languages which have exceptions in some way, yet I came to witness two "pathological" tendencies.

  1. There doesn't seem to be a common pattern or hierarchy of exceptions. Every language basically rolls its own version, and if the exceptions make it into the standard, then the kinds of exceptions that one finds in the standard would be rather arbitrary (mostly those which were implemented while creating language tools, such as reading source code from string or an exception to invoke debugger, or the one which happens when the file cannot be found etc.)

  2. Exceptions defined by the language are very rarely reused by user programs. There would be usually one or two popular exceptions ("not implement" for example). Though most times programmers will create their own exceptions. (Compare this to, for example, creating new numeric types or new collection types).

This looks like a terrible omission to me. How comes no one knows what kinds of errors will be needed in user programs? I was hoping for there to be a kind of nice hierarchy, similar to numeric types, collections, object system etc.

Worse yet, Goolge and Wikipedia provide very little help on the subject. So far I've only found a paper on functional exception which opens in a passage:

This paper argues that lazy functional programming not only makes built-in exception handling mechanism unnecessary, but provides a powerful tool for developing and transforming programs that use exceptions

(A Functional Theory of Exceptions, Mike Spivey, 1988)

But I think that exceptions are good. I don't want to transform programs that use exceptions, on the contrary, I want to make the use of exceptions less chaotic.

The question:

Is there a theory of exceptions? If so, what is it called? What are, if any, the cornerstone works outlining the basis of it?

wvxvw
  • 1,388
  • 9
  • 13

3 Answers3

8

There's a large number of publications on exceptions, with quite a few theoretical investigations. Here is an unstructured and far from complete list with some examples. Sorry, I don't have time at the moment for a more focussed reply.

  • B. Randell, System Structure for Software Fault Tolerance.
  • J. B. Goodenough. Exception handling: Issues and a proposed notation.
  • J. B. Goodenough. Structured exception handling.
  • B. G. Ryder, M. L. Soffa, Influences on the Design of Exception Handling.
  • D. Teller, A. Spiwack, T. Varoquaux, Catch me if you can: Towards type-safe, hierarchical, lightweight, polymorphic and efficient error management in OCaml.
  • X. Leroy, F. Pessaux, Type-based analysis of uncaught exceptions.
  • R. Miller, A. Tripathi, Issues with Exception Handling in Object-Oriented Systems.
  • S. Drew, K. J. Gough, J. Ledermann, Implementing Zero-Overhead Exception Handling.
  • B. Stroustrup, Exception Safety: Concepts and Techniques.
  • D. Malayeri, J. Aldrich, Practical Exception Specifications.
  • H. Nakano, A Constructive Formalization of the Catch and Throw Mechanism.
  • A. Nanevski, A Modal Calculus for Exception Handling.
  • P. de Groote, A Simple Calculus of Exception Handling.
  • H. Thielecke, On Exceptions and Continuations in Presence of State.
  • J. G. Riecke, H. Thielecke, Typed Exceptions and Continuations Cannot Macro-Express Each Other.
  • M. van Dooren, E. Steegmans, Combining the Robustness of Checked Exceptions with the Flexibility of Unchecked Exceptions using Anchored Exception Declarations.
  • J. A. Vaughan, A logical interpretation of Java-style exceptions.
  • S. Marlow, S. Peyton Jones, A. Moran, Asynchronous Exceptions in Haskell.
  • B. Jacobs, F. Piessens, Failboxes: Provably Safe Exception Handling.
Martin Berger
  • 8,358
  • 28
  • 47
6

I don't know whether or not there is a theory, but there may be an emerging pragmatic experimental science.

The best source I can think of is Bjarne Stroustrup, The Design and Evolution of C++, Addison-Wesley, 1994. If I remember correctly (it's a very good book and people keep borrowing it from me and not returning it, so I don't have a copy at the moment) there's a chapter about exceptions. The C++ committee under Stroustrup required a lot of empirical evidence that a proposed feature was necessary before they were willing to add it to the language definition. The Wikipedia page about exceptions has the following quote from that book:

At the Palo Alto [C++ standardization] 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.

In C++ the real win is RAII, which makes it much easier to handle resource deallocation during errors. (It doesn't do away with the need for throw and try-catch, but it means you don't need finally.)

I think the thing that convinced them they needed exceptions is generic containers: the container writer knows nothing about the kinds of errors that the contained objects might need to return (much less how to handle them), but the code that inserted those objects into the container must know something about what those objects' interface is. But since we know nothing about what kinds of errors the contained objects can throw, we can't standardize on exception types. (Contrapositively: if we could standardize exception types then we wouldn't need exceptions.)

The other thing that people seem to have learned over the years is that exception specifications are hard to put into a language correctly. See for example this: http://www.gotw.ca/publications/mill22.htm, or this: http://www.gotw.ca/gotw/082.htm. (And it's not just C++, Java programmers also have lengthy arguments about their experiences with checked versus unchecked exceptions.)

A little on the history of exceptions. The classic paper is: John B. Goodenough:"Exception handling: issues and a proposed notation," Commun. ACM 18(12):683-696, 1975. But exceptions were known before that. Mesa had them in about 1974, and PL/I may have had them too. Ada had an exception mechanism before 1980. I believe that C++'s exceptions were most influenced by the experience with Barbara Liskov's CLU programming language from about 1976. Barbara Liskov: "A history of CLU," in History of programming languages---II, Thomas J. Bergin, Jr. and Richard G. Gibson, Jr. (Eds.). pp. 471-510, ACM, 1996.

Wandering Logic
  • 17,863
  • 1
  • 46
  • 87
3

Let me just point out that exceptions are a case of computational effect. Other computational effects are mutable state, I/O, non-determinism, continuations, and many others. So your question could be asked more generally: how do we form hierarchies of computational effects, how do we organize them, and why do we have the ones we have, and not others, etc.

Andrej Bauer
  • 31,657
  • 1
  • 75
  • 121