Modula-3: Recursive declarations

## Recursive declarations

A constant, type, or procedure declaration `N = E`, a variable declaration `N: E`, an exception declaration `N(E)`, or a revelation `N = E` is recursive if `N` occurs in any partial expansion of `E`. A variable declaration `N := I` where the type is omitted is recursive if `N` occurs in any partial expansion of the type `E` of `I`. Such declarations are allowed if every occurrence of `N` in any partial expansion of `E` is (1) within some occurrence of the type constructor `REF` or `PROCEDURE`, (2) within a field or method type of the type constructor `OBJECT`, or (3) within a procedure body.

Examples of legal recursive declarations:

        TYPE
          List = REF RECORD x: REAL; link: List END;
          T = PROCEDURE(n: INTEGER; p: T);
          XList = X OBJECT link: XList END;
        CONST N = BYTESIZE(REF ARRAY [0..N] OF REAL);
        PROCEDURE P(b: BOOLEAN) = BEGIN IF b THEN P(NOT b) END END P;
        EXCEPTION E(PROCEDURE () RAISES {E});
        VAR v: REF ARRAY [0..BYTESIZE(v)] OF INTEGER;

Examples of illegal recursive declarations:

        TYPE
          T = RECORD x: T END;
          U = OBJECT METHODS m() := U.m END;
        CONST N = N+1;
        REVEAL I.T = I.T BRANDED OBJECT END;
        VAR v := P(); PROCEDURE P(): ARRAY [0..LAST(v)] OF T;

Examples of legal non-recursive declarations:

        VAR n := BITSIZE(n);
        REVEAL T <: T;

    Last modified on Wed Apr  3 09:38:58 PST 1996 by heydon
         modified on Mon Apr 18 14:06:26 PDT 1994 by kalsow