[net.lang] Escape structures

g-rh@cca.UUCP (Richard Harter) (04/07/86)

Summary: I proposed a language consisting of labelled blocks (or
loops) with an escape statement that left the labelled block via
a labelled 'fragment' of code.  It has been mentioned to me in
correspondence that the PL/I condition handler can be used in this
fashion.

In article <> savage@ssc-vax.UUCP (Lowell Savage) writes:
>....
>I beleve that Ada provides such a facility (with an "exit" statement
>which can take arguments that are block names) only without the
>FRAGMENT capability.  If there is some set of code that needs to be
>executed before the block is exited, then that code can come before
>the exit statement.  However, Ada also provides another mechanism
>which I think can be used for complete purpose intended by Richard.
>This is the exception mechanism.  The FRAGMENT is now the statements
>after the exception handler, and the "exit" or "escape" statement is
>now the Ada "RAISE" statement which raises some exception known only
>within that block of code.
>
	I knew (having written PL/I code for several years) about PL/I
ON conditions, but I am not acquainted with the similar mechanism in
ADA.  It sounds like the PL/I and Ada constructs are more or less
functionally equivalent to what I was suggesting, but not quite.
The question is, what happens to control after the exception handler
is done.  In PL/I it goes back to the point where the exception was
raised -- the escape is handled separately with a goto.  Thus:

	......
	if (problem) then raise(exception)
	......
LBL:

	......
exception_handler:
	......
	goto LBL

This is probably necessary for exception handlers which typically
either (a) fixup the problem and go back to where it came from or
(b) wrench control from the normal control stack and skip up multiple
levels, hopefully disposing of accumulated frames along the way.

	If I understand what Ada offers correctly, one has either
the automatic block exit or the fragment (handler) but not both at
the same time.  I could (but wont) dig up my Ada books and check it
out.

	Some more thoughts that occur to me in passing.  The first is
that I am not a fan of using labels to indicate the first statement
after a block of code, which all GOTO based solutions end up using;
I would prefer to have blocks labelled and have escape statements
which leave the block.  This is in direct analogy with 'return'
statements from procedures; I can escape from any level of nesting
within a procedure with a return statement -- I ought to be able
to do the same thing with internally nested blocks.  Come to think
of it, the BLOCK construct I was proposing is similar to a nested
procedure except that:

(a)	It is executed by falling through to it;
(b)	It is not invoked by name;
(c)	It is parameterless.

[Here is a construct that gives me the willies when I think about it:
a return statement that lets you specify what routine you are returning
from!  An escape statement that lets you escape from a block at a
higher level than the one you are in does this, but the legitmacy of
the escape can be checked at compile time.]

	Another thought is that the whole problem of exception
handling is a mess.  C's setjmp/longjmp mechanism is no more than
a "here is a low level primitive for the job -- you figure out
how to do it yourself" approach.  The PL/I ON condition handlers
are only a small cut above C.  It seems to me that the whole area
of error handling is in need of major theoretical analysis.

		Richard Harter, SMDS Inc.

rossiter@svax.cs.cornell.edu (David G. Rossiter) (04/09/86)

Richard Harter writes:
>
>	Another thought is that the whole problem of exception
>handling is a mess.  C's setjmp/longjmp mechanism is no more than
>a "here is a low level primitive for the job -- you figure out
>how to do it yourself" approach.  The PL/I ON condition handlers
>are only a small cut above C.  It seems to me that the whole area
>of error handling is in need of major theoretical analysis.
>
>		Richard Harter, SMDS Inc.

There is an *excellent* theoretical and practical analysis of error
handling in a recent PhD thesis by Andrew P. Black, from Balliol
College of Oxford University, UK.  The title is "Exception Handling:
the case against", submitted January 1982.  Black is now at Univ. of
Washington, I believe.  I have a copy of the thesis which I obtained
from the chairman of my PhD committee; I'm not sure where it is publically
available.  One could presumably email to Black.

Anyway, he examines in detail exception handling mechanisms in producation
languages like PL/I, Algol W, Algol 68, Mesa, and Ada, as well as in
academic (but implemented) languages like CLU.  He concludes that the
way to think of so-called "exceptions" is as named constituents of a
discriminated union data type (sort of like Pascal variant records, but
type secure).  It's very clean semantically and seems easy to program in
and write compilers for.  If there's more interest I can post the abstract
and summary.



David Rossiter / CS Dep't / Cornell University / Ithaca / NY / 14850 / USA
{uw-beaver,ihnp4,decvax,vax135}!cornell!rossiter (UUCP)
rossiter@gvax.cs.cornell.edu (ARPAnet) ; rossiter@CRNLCS (BITNET)

cdshaw@watdragon.UUCP (Chris Shaw) (04/13/86)

The most beautiful way I have seen for directed escape is with the
Waterloo System Language's (WSL)  GUESS-ADMIT structure.
The following details are probably wrong, but you will hopefully get the gist:

	GUESS : LABEL1 
		quif( some_condition ) : LABEL1	  /* quit guess completely*/
		quif( some_other_cond )	          /* goto admit */
		< processing >
	ADMIT : LABEL2			/* label optional */
		< different processing >
	ENDGUESS

"quif( cond )" means quit the local block if "cond" is true. If a label
follows in the quit statement, then the quif goes to the label. One can 
only go to labels (I recall) at your control statement level or "outer". 
For example, you can't quit into the body of a non-enclosing WHILE statement.

The semantics of quits and quifs are basically gotos which can only branch
DOWNWARDS. Therefore, no spaghetti code. This also makes for object code
efficiency, since there is rarely a case where one would have to do complicated
control structures. The GUESS-ADMIT structure is more or less a thinking
person's case statement. ADMITs can be added at will in a GUESS statement.
Thus the following could happen (code omitted between each GUESS or ADMIT):

	GUESS
	ADMIT :LABEL1
	ADMIT :LABEL2
	ADMIT :LABEL3
	ENDGUESS

Each ADMIT block handles one particular situation and no other. One can easily
tell by looking what is being done, and it is clear at a glance where control
passes to when processing for any ADMIT block is complete. The ADMIT labels
allow for quitting past ADMIT blocks that will fail anyway. 

Hopefully I haven't been too unclear here, but the point I'm trying to make
is this:
GOTOs are "evil" because they are generally unconstrained in their "scope".
The quif/quit structure answers this difficulty by allowing limited scope 
to where they can transfer control. All control function can be determined at
compile time, and the maximum scope available is the surrounding procedure.

(I used (and liked) this language a longish while ago. email me for more detail)

Chris Shaw    watmath!watrose!cdshaw  or  cdshaw@watmath
University of Waterloo
Bogus as HELL !!!

richw@ada-uts (04/18/86)

Another VERY good paper on the subject of exception handling:

    "A Modular Verifiable Exception-Handling Mechanism"
            by Shaula Yemini and Daniel M. Berry

in ACM's TOPLAS (Transactions on Programming Languages and Systems),
April 1985, Vol. 7., No. 2.

This paper includes a very intelligent comparison of the
exception handling mechanisms of several languages (most
notably, CLU and Ada).

Rich Wagner


P.S.  That TOPLAS issue also happens to include an article
      by William Weihl and Barbara Liskov (Prof. Liskov
      was the primary designer of CLU) entitled
      "Implementation of Resilient, Atomic Data Types".