Newsgroups: comp.lang.modula3
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!sdd.hp.com!elroy.jpl.nasa.gov!decwrl!pa.dec.com!src.dec.com!stolfi 
From: stolfi (Jorge Stolfi)
Subject: Re: Local exceptions
In-Reply-To: Message of Sat, 18 May 91 14:22:42 PDT
    from gnelson (Greg Nelson)
    <9105182122.AA09401@jumbo.pa.dec.com>
To: gnelson (Greg Nelson)
Message-ID: <9105202150.AA26760@jumbo.pa.dec.com>
Cc: m3
X-Folder-Carbon: lang-des
Date: Mon, 20 May 91 14:50:07 PDT
Lines: 112


Greg, thanks for your reply.  

However, I must say I didn't understand your example:

    PROCEDURE P(b: BOOLEAN) = 
      EXCEPTION E;
      BEGIN
        TRY
          IF b THEN 
            P(NOT b)
          ELSE
            RAISE E
          END
        EXCEPT
          E: (* Skip *)
        END
      END P;
    
I don't see what is the problem here, since the exception E is always
caught in the same frame where it is raised.  

If we substitute the body of P for the call, we get something like

    PROCEDURE P(b: BOOLEAN) = 
      EXCEPTION E;
      BEGIN
        TRY
          IF b THEN 
            WITH b = NOT b DO
              EXCEPTION E;
              BEGIN
                TRY
                  IF b THEN 
                    P(NOT b)
                  ELSE
                    RAISE E
                  END
                EXCEPT
                  E: (* Skip *)
                END
              END P;
            END
          ELSE
            RAISE E
          END
        EXCEPT
          E: (* Skip *)
        END
      END P;

which doesn't seem to pose any problems of interpretation. 

Perhaps you meant to write

    PROCEDURE P(b: BOOLEAN) = 
      EXCEPTION E;
      BEGIN
        IF b THEN 
          TRY P(NOT b) EXCEPT E: (* Skip *) END
        ELSE
          RAISE E
        END
      END P;

However, in this case the natural interpretation is that the RAISE
E is an error, since (according to the Twelve Changes) P has
an empty RAISES clause, and hence a call to P cannot raise E.

Am I confused?

I am also quite surprised by your assertion that local exceptions have
no real use.  Sure, they are not strictly necessary; but the same
can be said of local variables, types, constants, and procedures,
which you agree are Very Good Things. 

A typical use of local exceptions would be

  PROCEDURE Foo(..) =

    EXCEPTION NotFound;
    PROCEDURE Lookup(...) RAISES {NotFound} =
      BEGIN
        ...
      END Lookup;

    BEGIN
      ...
      TRY Lookup(...) EXCEPT NotFound => ... END;
      ...
    END Foo;

--jorge

PS.  By the way, the argument that "a procedure call should have the same
effect as its body" is not very convincing. Consider for example

   PROCEDURE F(n: INTEGER): REFANY =
     TYPE T = BRANDED REF INTEGER;
     BEGIN
       IF n = 0 THEN 
         WITH t = NEW(T) DO t^ := 0; RETURN t END
       ELSE
         RETURN F(n-1)
       END
     END F;

From this code, I would expect F(0) and F(1) to have the same typecode
(and the SRC compiler seems to agree.)  However, if we substitute the
body of F for the call F(n-1), we will get two declarations of type
T, and the brands of F(0) and F(1) will be different.

