## ﻿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.