## 8.1 Recursive definitions of values

(Introduced in Objective Caml 1.00)

As mentioned in section 7.7.2, the let rec binding construct, in addition to the definition of recursive functions, also supports a certain class of recursive definitions of non-functional values, such as

let rec name1 = 1 :: name2 and name2 = 2 :: name1 in expr

which binds name1 to the cyclic list 1::2::1::2::…, and name2 to the cyclic list 2::1::2::1::…Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.

More precisely, consider the expression:

let rec name1 = expr1 and … and namen = exprn in expr

It will be accepted if each one of expr1 … exprn is statically constructive with respect to name1 … namen, is not immediately linked to any of name1 … namen, and is not an array constructor whose arguments have abstract type.

An expression e is said to be statically constructive with respect to the variables name1 … namen if at least one of the following conditions is true:

- e has no free occurrence of any of name1 … namen
- e is a variable
- e has the form fun … -> …
- e has the form function … -> …
- e has the form lazy ( … )
- e has one of the following forms, where each one of expr1 … exprm is statically constructive with respect to name1 … namen, and expr0 is statically constructive with respect to name1 … namen, xname1 … xnamem:
  - let [rec] xname1 = expr1 and … and xnamem = exprm in expr0
  - let module … in expr1
  - constr ( expr1, … , exprm)
  - ` tag-name ( expr1, … , exprm)
  - [| expr1; … ; exprm |]
  - { field1 = expr1; … ; fieldm = exprm }
  - { expr1 with field2 = expr2; … ; fieldm = exprm } where expr1 is not immediately linked to name1 … namen
  - ( expr1, … , exprm )
  - expr1; … ; exprm

An expression e is said to be immediately linked to the variable name in the following cases:

- e is name
- e has the form expr1; … ; exprm where exprm is immediately linked to name
- e has the form let [rec] xname1 = expr1 and … and xnamem = exprm in expr0 where expr0 is immediately linked to name or to one of the xnamei such that expri is immediately linked to name.