[comp.lang.modula2] Bob Campbell's exception handler

klaiber@dewey.udel.edu.UUCP (02/15/87)

I couldn't resist adding my comments to Bob Campbell's suggestion on how to
implement exceptions in Modula-2:

<FLAME on>	-- this is going to be a LONG comment

First of all, I am not sure how you want to abort a procedure when an error
occurs: In Ada, when an error occurs at point [1] (below), control is
transferred to the handler [3] and the procedure is exited thereafter
(provided no exceptions were raised in the handler) WITHOUT executing 
part [2] of the statements.

      begin
	 <some call that may raise Error> [1]
	 <other code>			  [2]
      exception
	 when Error => <handle>		  [3]
      end;

Now, how do you do this in Modula-2? I have the impression that the only
way to do it is like this:

      PROCEDURE P;
      BEGIN (*proc*)
	 IF Handle(Error)=firstCall THEN
	    <the body of the procedure>
	    FreeHandler(Error);
	 ELSE
	    <place the handler code here>
	 END;
      END; (*proc*)

That is, have Handle(..) install a handler for <Error>, do a 'setjmp' and
then return <firstCall>.
When an exception occurs, thus causing 'longjmp' to be executed, 'Handle'
would return a second time (remember, 'setjmp' was called from inside
'Handle' and 'longjump' causes 'setjmp' to return a second time, so we're
in 'Handle' again -- which was called at the beginning of our procedure P)
Now when Handle returns the first time (after installing the handler), we
want to execute the body of the procedure next, but on the second return,
we should execute the handler and then exit the procedure (instead of
executing it again from the start, causing the error to occur again, ....)

To summarize it briefly: For Ada-style exceptions, we want to exit the
procedure/block in which the error occured (immediately after executing the
handler). This corresponds to a GOTO/longjmp to the end of the procedure.
However, without actually executing the code at the end of the procedure,
we cannot make setjmp/longjmp jump to it. The only thing we can do (I
think) is -- on exceptions -- transfer control to the place where the
handler was installed and hence, we need the awkward scheme described
above.

=== I'd really appreciate some comments on this : Am I missing some
=== essential detail here???

Now even if the above problem can be solved, two objections remain (one
minor, the other major):

   (1) The use of these exceptions is restricted to user-defined
       exceptions; i.e. errors such as overflow on multiplication or array
       index out of range cannot be caught without INTEGRATING the
       exception handler into the language (the compiler, that is).
   (2) The more serious problem: The mechanism proposed is too powerful, as
       the compiler has no way of insuring proper use of the package:
       The sore point is that the programmer is responsible for properly
       installing and Free'ing handlers. Now my assumption is that
       programmers (including myself) are stupid and need as much help as
       possible from the compiler/system/...
       Consider the following case:
         PROCEDURE Outer;
	    PROCEDURE Inner;
	    BEGIN
	       Handle(Error,Handler);
	       ...
	       (* forgot to call FreeHandler *)
	    END Inner;
	 BEGIN (*outer*)
	    Handle(Error,InnerHandler);
	    Inner(..);
	    ...
	    <some stmt here causes Error to be raised>
	    ...
	    FreeHandler(Error);
	 END Outer;
       Here, the handler for procedure Inner would be called to deal with an
       error that occured in procedure Outer -- not really desirable!!

One final note: If one has to use the syntax described above (i.e. the 
'IF Handler(..)=firstCall THEN body ELSE handler END'), then the above
problem could even cause a jump back into the Inner procedure at a time
that Inner is not active! Can you imagine the consequences....


So for me, the bottom line is: If you want a language that handles
exceptions in a half-decent way, don't use Modula-2  .... wait for 
Modula-3 instead!!!


	Alexander Klaiber
	(klaiber@dewey.udel.edu)

<usual disclaimers etc etc etc...>