This chapter describes language extensions and convenience features
that are implemented in Objective Caml, but not described in the
Objective Caml reference manual.
7.1 
Integer literals for types int32, int64 and nativeint 

int32literal 
::= 
integerliteral l 
int64literal 
::= 
integerliteral L 
nativeintliteral 
::= 
integerliteral n 
An integer literal can be followed by one of the letters l, L or n
to indicate that this integer has type int32, int64 or nativeint
respectively, instead of the default type int for integer literals.
The library modules Int32[Int32],
Int64[Int64] and Nativeint[Nativeint]
provide operations on these integer types.
7.2 
Streams and stream parsers 

Streams and stream parsers are no longer part of the Objective Caml
language, but available through a Camlp4 syntax extension. See the
Camlp4 reference manual for more information. Objective Caml programs
that use streams and stream parsers can be compiled with the
pp camlp4o option to ocamlc and ocamlopt. For interactive use,
run ocaml and issue the #load "camlp4o.cma";;
command.
7.3 
Recursive definitions of values 

As mentioned in section 6.7.1, the let rec binding
construct, in addition to the definition of recursive functions,
also supports a certain class of recursive definitions of
nonfunctional values, such as
let rec name_{1} = 1 :: name_{2}
and name_{2} = 2 :: name_{1}
in expr
which binds name_{1} to the cyclic list 1::2::1::2::..., and
name_{2} 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 name_{1} = expr_{1} and ... and name_{n} = expr_{n} in expr
It will be accepted if each one of expr_{1} ... expr_{n} is
statically constructive with respect to name_{1} ... name_{n} and
not immediately linked to any of name_{1} ... name_{n}
An expression e is said to be statically constructive
with respect to the variables name_{1} ... name_{n} if at least
one of the following conditions is true:

e has no free occurrence of any of name_{1} ... name_{n}
 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
expr_{1} ... expr_{m} is statically constructive with respect to
name_{1} ... name_{n}, and expr_{0} is statically constructive with
respect to name_{1} ... name_{n}, xname_{1} ... xname_{m}:

let [rec] xname_{1} = expr_{1} and ...
and xname_{m} = expr_{m} in expr_{0}
 let module ... in expr_{1}
 constr ( expr_{1}, ... , expr_{m})
 `tagname ( expr_{1}, ... , expr_{m})
 [ expr_{1}; ... ; expr_{m} ]
 { field_{1} = expr_{1}; ... ; field_{m} = expr_{m} }
 { expr_{1} with field_{2} = expr_{2}; ... ;
field_{m} = expr_{m} } where expr_{1} is not immediately
linked to name_{1} ... name_{n}
 ( expr_{1}, ... , expr_{m} )
 expr_{1}; ... ; expr_{m}
An expression e is said to be immediately linked to the variable
name in the following cases:

e is name
 e has the form expr_{1}; ... ; expr_{m} where expr_{m}
is immediately linked to name
 e has the form let [rec] xname_{1} = expr_{1} and ...
and xname_{m} = expr_{m} in expr_{0} where expr_{0} is immediately
linked to name or to one of the xname_{i} such that expr_{i}
is immediately linked to name.
In patterns, Objective Caml recognizes the form
' c ' .. ' d '
(two character literals separated by ..) as shorthand for the pattern
' c '  ' c_{1} '  ' c_{2} '  ...
 ' c_{n} '  ' d '
where c_{1}, c_{2}, ..., c_{n} are the characters
that occur between c and d in the ASCII character set. For
instance, the pattern '0'..'9' matches all characters that are digits.
Objective Caml supports the assert construct to check debugging assertions.
The expression assert expr evaluates the expression expr and
returns () if expr evaluates to true. Otherwise, the exception
Assert_failure is raised with the source file name and the
location of expr as arguments. Assertion
checking can be turned off with the noassert compiler option.
As a special case, assert false is reduced to
raise (Assert_failure ...), which is polymorphic (and
is not turned off by the noassert option).
The expression lazy expr returns a value v of type Lazy.t that
encapsulates the computation of expr. The argument expr is not
evaluated at this point in the program. Instead, its evaluation will
be performed the first time Lazy.force is applied to the value
v, returning the actual value of expr. Subsequent applications
of Lazy.force to v do not evaluate expr again.
For more information, see the description of module Lazy in the
standard library (see
Module Lazy).
The expression
let module modulename = moduleexpr in expr
locally binds the module expression moduleexpr to the identifier
modulename during the evaluation of the expression expr.
It then returns the value of expr. For example:
let remove_duplicates comparison_fun string_list =
let module StringSet =
Set.Make(struct type t = string
let compare = comparison_fun end) in
StringSet.elements
(List.fold_right StringSet.add string_list StringSet.empty)
typerepresentation 
::= 
... 

 
= private constrdecl {  constrdecl } 

 
= private { fielddecl { ; fielddecl } } 
Private types are variant or record types. Values of
these types can be destructured normally in patternmatching or via
the expr . field notation for record accesses. However, values of
these types cannot be constructed directly by constructor application
or record construction. Moreover, assignment on a mutable field of a
private record type is not allowed.
The typical use of private types is in the export signature of a
module, to ensure that construction of values of the private type always
go through the functions provided by the module, while still allowing
patternmatching outside the defining module. For example:
module M : sig
type t = private A  B of int
val a : t
val b : int > t
end
= struct
type t = A  B of int
let a = A
let b n = assert (n > 0); B n
end
Here, the private declaration ensures that in any value of type
M.t, the argument to the B constructor is always a positive integer.
definition 
::= 
... 

 
module rec modulename : moduletype = moduleexpr
{ and modulename: moduletype = moduleexpr } 
specification 
::= 
... 

 
module rec modulename : moduletype
{ and modulename: moduletype } 
Recursive module definitions, introduced by the 'module rec' ...'and' ... construction, generalize regular module definitions
module modulename = moduleexpr and module specifications
module modulename : moduletype by allowing the defining
moduleexpr and the moduletype to refer recursively to the module
identifiers being defined. A typical example of a recursive module
definition is:
module rec A : sig
type t = Leaf of string  Node of ASet.t
val compare: t > t > int
end
= struct
type t = Leaf of string  Node of ASet.t
let compare t1 t2 =
match (t1, t2) with
(Leaf s1, Leaf s2) > Pervasives.compare s1 s2
 (Leaf _, Node _) > 1
 (Node _, Leaf _) > 1
 (Node n1, Node n2) > ASet.compare n1 n2
end
and ASet : Set.S with type elt = A.t
= Set.Make(A)
It can be given the following specification:
module rec A : sig
type t = Leaf of string  Node of ASet.t
val compare: t > t > int
end
and ASet : Set.S with type elt = A.t
This is an experimental extension of Objective Caml: the class of
recursive definitions accepted, as well as its dynamic semantics are
not final and subject to change in future releases.
Currently, the compiler requires that all dependency cycles between
the recursivelydefined module identifiers go through at least one
``safe'' module. A module is ``safe'' if all value definitions that
it contains have function types ty_{1} > ty_{2}. Evaluation of a
recursive module definition proceeds by building initial values for
the safe modules involved, binding all (functional) values to
fun x > raise Undefined_recursive_module. The defining
module expressions are then evaluated, and the initial values
for the safe modules are replaced by the values thus computed. If a
function component of a safe module is applied during this computation
(which corresponds to an illfounded recursive definition), the
Undefined_recursive_module exception is raised.