[comp.lang.modula2] Exception handling

crb@SUN.COM.UUCP (02/09/87)

> Could we get a discussion going on exception handling in Modula-2? ...

I agree with the opinion expressed by some others that the lack of a
defined mechanism for dealing with exceptional conditions is a shortcoming.
And I do not believe that such capability is in violation of the principles
of gotoless programming, if designed in such a way that the potential
behavior of a program is easy to understand by static inspection of the
program text.

I think setjmp/longjmp is truly awful -- the user's program flow becomes 
extremely convoluted -- and the routines themselves are quite ugly, too.

One could argue that other languages (COBOL, FORTRAN, ... ) have gotten
along quite well without any defined exception-handling capability, but
these aren't languages in the same league, or of the same "generation"
as are Modula-2 and Ada.  Personally, I'd like to see this particular
capability made part of the language, if it was cheap to implement and
cheap at runtime.   And I'd a lot rather see it made part of the standard
than to have umpteen different vendors go off and invent umpteen different
ways to do it.  And at least umpteen will do so.

In light of this, I'd like to suggest that people interested in the
topic would do well to consider the proposal put forth by Martin Odersky,
Peter Sollich, and Mike Weisert of Borland International,  which was
written up in the November '85 issue of the MODUS quarterly (page 13).
I think it makes pretty good sense; it's "elegant" and it wouldn't cost too
much to implement.  The only disagreement I've got with it is their idea
of the RAISE construct optionally allowing a character string, and then
not making that string available to the handler which captures the exception.


-- Chuck Bilbe
   Modula-2 Project Leader
   Sun Microsystems

(* the opinions expressed here are my own and don't necessarily *)
(* reflect the opinions or plans of Sun Microsystems.           *)

johnl@ee.brunel.ac.uk (John Lancaster) (03/13/87)

> Could we get a discussion going on exception handling in Modula-2? ...

What is an Exception?  A exception occurs when something unexpected happens
during runtime.  Exceptions can be caused by overflow, range, address errors
or raised by the programmer.

What is an Exception handler?  An exception handler is a block of code to
which control will be transferred when the exception occurs.  Control is NOT
returned to the point at which the exception was raised.  Instead it is
passed to a procedure higher up the call tree and the intervening stack is
discarded.  e.g. A calls B calls C calls D.  If D raises an exception which
B is programmed to handle, control will be returned to some point in B and
the stack will look as if C and D were never called.
 
To date two approaches have been put forward.  The first (by Bob Campbell
and others) tries to implement exception handling as library procedures
containing some low-level code.  If this scheme works (I don't think it
will) it will have the following advantages:

  1- Requires no change to the language
  2- Can be enabled and disabled over any size code block

and the following disadvantages:

  1- Not integrated with 'compiler' raised exceptions
  2- Has the runtime overhead of installing and de-installing handlers
  3- Is very unsafe

The second (by Martin Odersky and others) extends the language.  It was
printed in the November '85 issue of MODUS Quarterly.  I have appended an
extract to the end of this article.  This scheme has the following
advantages:

  1- Safe
  2- Integrated with 'compiler' raised exceptions
  3- Almost no runtime overhead during normal operation
  4- Simple to implement (similar to Exit in USCD Pascal)

and the following disadvantages:

  1- Requires an extension to the language
  2- Operates at procedure and module level

I would like to see both approaches the subject of further net discussion.

John Lancaster                  JANET: johnl@uk.ac.brunel.ee 
Brunel University               ARPA: johnl%ee.brunel.ac.uk@UCL-CS.ARPA 
Uxbridge 
England 
UB8 3PH 

Syntax and Semantics of Proposed Exception Handling Language Extension

Declaration of Exceptions

An exception declaration is similar to other declarations.  There is a
special keyword (EXCEPTION) followed by a list of identifiers.  Example
(taken from the module Files):

   EXCEPTION
     EndError, StatusError, UseError, DeviceError, DiskFull;

All the usual scope rules of Modula apply.  Exception identifiers can be
exported and imported like normal Modula identifiers.

Raising Exceptions

Exceptions are raised when the program detects an error condition.  (For
example, when the module Files has detected that the disk is full).  Raising
an exception will transfer control to an exception handler, either provided
by the user or the system.

A program may raise an exception with the reserved word RAISE followed by
the exception identifier and optionally by a string.  Example (taken from
MathLib):

  IF x < 0.0 THEN
    RAISE ArgumentError, 'Negative argument for Sqrt';  
  END;

When an exception is raised, the system looks in the current procedure for a
matching exception handler.  If none is found, the calling procedure is
examined, then the caller of that procedure, and so on, until a matching
exception handler is found.  This handler is then executed, and the
procedure containing the handler is exited.  If no handler is found, the
system prints the exception identifier's name and the optional message
string.  

Handling Exceptions

Exception handlers are written at the end of procedures and modules to
handle exceptions issued by a RAISE statement.  The syntax is similar to the
familiar CASE statement.  Example of a save procedure containing an
exception handler:

   PROCEDURE SaveFile;
   BEGIN
     (*Code to write something to disk*)
   EXCEPTION
     |  DiskFull  :
          Terminal.WriteString("Disk Full, Press <ESC>");
          REPEAT Terminal.ReadChar (ch) UNTIL ch = CHR(27);
     |  DeviceError:
          Terminal.WriteString("Bad Disk, Press <ESC>");
          REPEAT Terminal.ReadChar (ch) UNTIL ch = CHR(27);
   ENC SaveFile;
An exception handler may catch and then pass on an error condition with a
special form of the RAISE statement.  This form is not followed by an
exception identifier or message string.