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;