### 2.4.8 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;
```

m3-support@elego.de