-------------------------------------
This file has been translated from LaTeX by HeVeA.

5.7.4  Operators
=-=-=-=-=-=-=-=-

  Symbols from the class infix-symbols, as well as the keywords *, =, or and &,
can appear in infix position (between two expressions). Symbols from the class
prefix-symbols can appear in prefix position (in front of an expression).
  Infix and prefix symbols do not have a fixed meaning: they are simply
interpreted as applications of functions bound to the names corresponding to
the symbols. The expression prefix-symbol expr is interpreted as the
application ( prefix-symbol ) expr. Similarly, the expression expr_1
infix-symbol expr_2 is interpreted as the application ( infix-symbol ) expr_1
expr_2.
  The table below lists the symbols defined in the initial environment and
their initial meaning. (See the description of the standard library module
Pervasive in chapter Chapter 16 for more details). Their meaning may
be changed at any time using let ( infix-op ) name_1 name_2 = ...

               ------------------------------------------------
               | Operator  |         Initial meaning          |
               ------------------------------------------------
               |+          |Integer addition.                 |
               |- (infix)  |Integer subtraction.              |
               |- (prefix) |Integer negation.                 |
               |*          |Integer multiplication.           |
               |           |Integer division.  Raise          |
               |           |Division_by_zero if second        |
               |/          |argument is zero. The result is   |
               |           |unspecified if either argument is |
               |           |negative.                         |
               |           |Integer modulus. Raise            |
               |           |Division_by_zero if second        |
               |mod        |argument is zero. The result is   |
               |           |unspecified if either argument is |
               |           |negative.                         |
               |           |Bitwise logical ``and'' on        |
               |land       |integers.                         |
               |           |Bitwise logical ``or'' on         |
               |lor        |integers.                         |
               |           |Bitwise logical ``exclusive or''  |
               |lxor       |on integers.                      |
               |           |Bitwise logical shift left on     |
               |lsl        |integers.                         |
               |           |Bitwise logical shift right on    |
               |lsr        |integers.                         |
               |           |Bitwise arithmetic shift right on |
               |asr        |integers.                         |
               |+.         |Floating-point addition.          |
               |-. (infix) |Floating-point subtraction.       |
               |-. (prefix)|Floating-point negation.          |
               |*.         |Floating-point multiplication.    |
               |/.         |Floating-point division.          |
               |**         |Floating-point exponentiation.    |
               |@          |List concatenation.               |
               |^          |String concatenation.             |
               |           |Dereferencing (return the current |
               |!          |contents of a reference).         |
               |           |Reference assignment (update the  |
               |           |reference given as first argument |
               |:=         |with the value of the second      |
               |           |argument).                        |
               |=          |Structural equality test.         |
               |<>         |Structural inequality test.       |
               |==         |Physical equality test.           |
               |!=         |Physical inequality test.         |
               |<          |Test ``less than''.               |
               |<=         |Test ``less than or equal''.      |
               |>          |Test ``greater than''.            |
               |>=         |Test ``greater than or equal''.   |
               ------------------------------------------------

5.7.5  Objects
=-=-=-=-=-=-=-

Object creation
---------------

  new@new
  When class-path evaluates to a class body, new class-path evaluates to an
object containing the instance variables and methods of this class.
  When class-path evaluates to a class function, new class-path evaluates to a
function expecting the same number of arguments and returning a new object of
this class.
Message sending
---------------

  The expression expr # method-name invokes the method method-name of the
object denoted by expr.
Coercion
--------

  The type of an object can be coerced (weakened) to a supertype. The
expression ( expr :> typexpr ) coerces the expression expr to type typexpr. The
expression ( expr : typexpr_1 :> typexpr_2 ) coerces the expression expr from
type typexpr_1 to type typexpr_2. The former operator will sometimes fail to
coerce an expression expr from a type t_1 to a type t_2 even if type t_1 is a
subtype of type t_2. In this case, the latter operator should be used.
  In a class definition, coercion to the type this class defines is the
identity, as this type abbreviation is not yet completely defined.
Object duplication
------------------

  An object can be duplicated using the library function Oo.copy (see section
Section 17-17). Inside a method, the expression  {< inst-var-name = expr {
; inst-var-name = expr } >} returns a copy of self with the given instance
variables replaced by the values of the associated expressions; other instance
variables have the same value in the returned object as in self.

5.8  Type and exception definitions
===================================

5.8.1  Type definitions
=-=-=-=-=-=-=-=-=-=-=-=

  Type definitions bind type constructors to data types: either variant types,
record types, type abbreviations, or abstract data types. They also bind the
value constructors and record labels associated with the definition.
  type@type
      type-definition ::=   type typedef { and typedef }

                 typedef ::=   [type-params] typeconstr-name [type-equation]
                  [type-representation]  { type-constraint }
        type-equation ::=   = typexpr

  type-representation ::=   = constr-decl { | constr-decl }

                        |  = { label-decl { ; label-decl } }

          type-params ::=   ' ident

                        |  ( ' ident { , ' ident } )

          constr-decl ::=   cconstr-name

                        |  ncconstr-name of typexpr

           label-decl ::=   label-name : typexpr

                        |  mutable label-name : typexpr

      type-constraint ::=   constraint ' ident = typexpr

   mutable@mutable constraint@constraint
  Type definitions are introduced by the type keyword, and consist in one or
several simple definitions, possibly mutually recursive, separated by the and
keyword. Each simple definition defines one type constructor.
  A simple definition consists in a lowercase identifier, possibly preceded by
one or several type parameters, and followed by an optional type equation, then
an optional type representation, and then a constraint clause. The identifier
is the name of the type constructor being defined.
  The optional type parameters are either one type variable ' ident, for type
constructors with one parameter, or a list of type variables
('ident_1,...,'ident_n), for type constructors with several parameters. These
type parameters can appear in the type expressions of the right-hand side of
the definition.
  The optional type equation = typexpr makes the defined type equivalent to the
type expression typexpr on the right of the = sign: one can be substituted for
the other during typing. If no type equation is given, a new type is generated:
the defined type is incompatible with any other type.
  The optional type representation describes the data structure representing
the defined type, by giving the list of associated constructors (if it is a
variant type) or associated labels (if it is a record type). If no type
representation is given, nothing is assumed on the structure of the type
besides what is stated in the optional type equation.
  The type representation = constr-decl { | constr-decl } describes a variant
type. The constructor declarations constr-decl_1, ..., constr-decl_n describe
the constructors associated to this variant type. The constructor declaration
ncconstr-name of typexpr declares the name ncconstr-name as a non-constant
constructor, whose argument has type typexpr. The constructor declaration
cconstr-name declares the name cconstr-name as a constant constructor.
Constructor names must be capitalized.
  The type representation = { label-decl { ; label-decl } } describes a record
type. The label declarations label-decl_1, ..., label-decl_n describe the
labels associated to this record type. The label declaration label-name :
typexpr declares label-name as a label whose argument has type typexpr. The
label declaration mutable label-name : typexpr mutable@mutable behaves
similarly; in addition, it allows physical modification over the argument to
this label.
  The two components of a type definition, the optional equation and the
optional representation, can be combined independently, giving rise to four
typical situations:

 Abstract type: no equation, no representation.
 When appearing in a module signature, this definition specifies nothing on the
   type constructor, besides its number of parameters:  its representation is
   hidden and it is assumed incompatible with any other type.

 Type abbreviation: an equation, no representation.
 This defines the type constructor as an abbreviation for the type expression
   on the right of the = sign.

 New variant type or record type: no equation, a representation.
 This generates a new type constructor and defines associated constructors or
   labels, through which values of that type can be directly built or
   inspected.

 Re-exported variant type or record type: an equation, a representation.
 In this case, the type constructor is defined as an abbreviation for the type
   expression given in the equation, but in addition the constructors or labels
   given in the representation remain attached to the defined type constructor.
   The type expression in the equation part must agree with the representation:
   it must be of the same kind (record or variant) and have exactly the same
   constructors or labels, in the same order, with the same arguments.

  constraint@constraint The construct  constraint ' ident = typexpr  allows to
specify type parameters. Any actual type argument corresponding to the type
parameter ident have to be an instance of typexpr (more precisely, ident and
typexpr are unified). Type variables of typexpr can appear in the type equation
and the type declaration.

5.8.2  Exception definitions
=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    exception@exception
                exception-definition ::=   exception constr-decl

  Exception definitions add new constructors to the built-in variant type `exn'
of exception values. The constructors are declared as for a definition of a
variant type.

5.9  Classes
============

  Classes are defined using a small language, similar to the module language.

5.9.1  Class types
=-=-=-=-=-=-=-=-=-

  Class types are the class-level equivalent of type expressions: they specify
the general shape and type properties of classes.
  object@object end@end inherit@inherit val@val mutable@mutable method@method
private@private virtual@virtual constraint@constraint
            class-type ::=
                         |  class-body-type
                         |  typexpr -> class-type
       class-body-type ::=   object [( typexpr )] {class-field-spec} end
                         |  class-path
                         |  [ typexpr {, typexpr} ] class-path
      class-field-spec ::=   inherit class-type
                         |  val [mutable] inst-var-name : typexpr
                         |  method [private] method-name : typexpr
                         |  method [private] virtual method-name : typexpr
                         |  constraint typexpr = typexpr

Simple class expressions
------------------------

  The expression class-path is equivalent to the class type bound to the name
class-path. Similarly, the expression [ typexpr_1 , ... typexpr_n ] class-path
is equivalent to the parametric class type bound to the name class-path, in
which type parameters have been instanciated to respectively typexpr_1,
...typexpr_n.
Class function type
-------------------

  The class type expression typexpr -> class-type is the type of class
functions (functions from values to classes) that take as argument a value of
type typexpr and return as result a class of type class-type.
Class body type
---------------

  The class type expression object [( typexpr )] {class-field-spec} end is the
type of a class body. It specifies its instance variables and methods. In this
type, typexpr is match agains self type, therefore provinding a binding for
self type.
  A class body will match a class body type if it provides definitions for all
the components specified in the class type, and these definitions meet the type
requirements given in the class type. Furthermore, all methods either virtual
or public present in the class body must also be present in the class type (on
the other hand, some instance variables and concrete private methods may be
omitted). A virtual method will match a concrete method, thus allowing to
forget its implementation. An immutable instance variable will match a mutable
instance variable.
Inheritance
-----------

  inherit@inherit
  The inheritance construct inherit class-type allows to include methods and
instance variables from other classes types. The instance variable and method
types from this class type are added into the current class type.
Instance variable specification
-------------------------------

  val@val mutable@mutable
  A specification of an instance variable is written val [mutable]
inst-var-name : typexpr, where inst-var-name is the name of the instance
variable and typexpr its expected type. The flag mutable indicates whether this
instance variable can be physically modified.
  An instance variable specification will hide any previous specification of an
instance variable of the same name.
Method specification
--------------------

  method@method private@private
  A specification of an method is written method [private] method-name :
typexpr, where method-name is the name of the method and typexpr its expected
type. The flag private indicates whether the method can be accessed from
outside the class.
  Several specification for the same method must have compatible types.
Virtual method specification
----------------------------

  virtual@virtual method@method private@private
  Virtual method specification is written method [private] virtual method-name
: typexpr, where method-name is the name of the method and typexpr its expected
type.
Constraints on type parameters
------------------------------

  constraint@constraint
  The construct constraint typexpr_1 = typexpr_2 forces the two type
expressions to be equals. This is typically used to specify type parameters:
they can be that way be bound to a specified type expression.

5.9.2  Class expressions
=-=-=-=-=-=-=-=-=-=-=-=-

  Class expressions are the class-level equivalent of value expressions: they
evaluate to classes, thus providing implementations for the specifications
expressed in class types.
  object@object end@end fun@fun let@let rec@rec in@in and@and inherit@inherit
as@as val@val mutable@mutable method@method private@private virtual@virtual
constraint@constraint initializer@initializer
      class-expr ::=   class-path
                   |  [ typexpr {, typexpr} ] class-path
                   |  ( class-expr )
                   |  ( class-expr : class-type )
                   |  class-expr expr
                                   +
                   |  fun {pattern}  -> class-expr
                   |  let [rec] let-binding {and let-binding} in class-expr
                   |  object [( pattern [: typexpr] )] { class-field } end
     class-field ::=   inherit class-expr [as value-name]
                   |  val [mutable] inst-var-name = expr
                   |  method [private] method-name {pattern} = expr
                   |  method [private] virtual method-name : typexpr
                   |  constraint typexpr = typexpr
                   |  initializer expr

Simple class expressions
------------------------

  The expression class-path evaluates to the class bound to the name
class-path. Similarly, the expression [ typexpr_1 , ... typexpr_n ] class-path
evaluates to the parametric class bound to the name class-path, in which type
parameters have been instanciated to respectively typexpr_1, ...typexpr_n.
  The expression ( class-expr ) evaluates to the same module as class-expr.
  The expression ( class-expr : class-type ) checks that class-type match the
type of class-expr (that is, that the implementation class-expr meets the type
specification class-type). The whole expression evaluates to the same class as
class-expr, except that all components not specified in class-type are hidden
and can no longer be accessed.
Class application
-----------------

  Class application is denoted by juxtaposition of expressions. The expression
class-expr expr evaluates the expressions class-expr and expr. The expression
class-expr must evaluate to a functional class value, which is then applied to
the value of expr.
Class function
--------------

  The expression fun pattern -> class-expr evaluates to a function from values
to classes. When this function is applied to a value v, this value is matched
against the pattern pattern and the result is the result of the evaluation of
class-expr in the extended environment.
  The expression
                    fun pattern_1 ... pattern_n -> class-expr
   is a short form for
                   fun pattern_1 -> ... fun pattern_n -> expr

Local definitions
-----------------

  The let and let rec constructs bind value names locally, as for the core
language expressions.
Class body
----------

  The expression object ( pattern [: typexpr] ) { class-field } end denotes a
class body. This is the prototype for an object : it lists the instance
variables and methods of an objet of this class.
  A class body is a class value: it is not evaluated at once. Rather, its
components are evaluated each time an object is created.
  In a class body, the pattern ( pattern [: typexpr] ) is matched against self,
therefore provinding a binding for self and self type. Self can only be used in
method and initializers.
  Self type cannot be a closed object type, so that the class remains
extensible.
Inheritance
-----------

  inherit@inherit
  The inheritance construct inherit class-expr allows to reuse methods and
instance variables from other classes. The class expression class-expr must
evaluate to a class body. The instance variables, methods and initializers from
this class body are added into the current class. The addition of a method will
override any previously defined methods of the same name.
  as@as An ancestor can be bound by prepending the construct as value-name to
the inheritance construct above. value-name is not a true variable and can only
be used to select a method, i.e. in an expression value-name # method-name.
This gives access to the method method-name as it was defined in the parent
class even if it is redefined in the current class.  The scope of an ancestor
binding is limited to the current class.  The ancestor method may be called
from a subclass but only indirectly.
Instance variable definition
----------------------------

  val@val mutable@mutable
  The definition val [mutable] inst-var-name = expr adds an instance variable
inst-var-name whose initial value is the value of expression expr. Several
variables of the same name can be defined in the same class. The flag mutable
allows physical modification of this variable by methods.
  An instance variables can only be used in the following methods and
initializers of the class.
Method definition
-----------------

  method@method private@private
  Method definition is written method method-name = expr. The definition of a
method overrides any previous definition of this method. The method will be
public (that is, not private) if any of the definition states so.
  A private method, method private method-name = expr, is a method that can
only be invoked on self (from other methods of the current class as well as of
subclasses of the current class). This invocation is performed using the
expression value-name # method-name, where value-name is directly bound to self
at the beginning of the class definition. Private methods do not appear in
object types.
  Some special expressions are available in method bodies for manipulating
instance variables and duplicating self:
      expr ::=   ...
             |  inst-var-name <- expr
             |  {< [ inst-var-name = expr { ; inst-var-name = expr } ] >}

  The expression inst-var-name <- expr modifies in-place the current object by
replacing the value associated to inst-var-name by the value of expr. Of
course, this instance variable must have been declared mutable.
  The expression {< [ inst-var-name = expr { ; inst-var-name = expr } ] >}
evaluates to a copy of the current object in which the values of instance
variables inst-var-name_1, ..., inst-var-name_n have been replaced by the
values of the corresponding expressions expr_1, ..., expr_n.
Virtual method definition
-------------------------

  virtual@virtual method@method private@private
  Method specification is written method [private] virtual method-name :
typexpr. It specifies whether the method is public or private, and gives its
type.
Constraints on type parameters
------------------------------

  constraint@constraint
  The construct constraint typexpr_1 = typexpr_2 forces the two type
expressions to be equals. This is typically used to specify type parameters:
they can be that way be bound to a specified type expression.
Initializers
------------

  initializer@initializer
  A class initializer initializer expr specifies an expression that will be
evaluated when an object will be created from the class, once all the instance
variables have been initialized.

5.9.3  Class definitions
=-=-=-=-=-=-=-=-=-=-=-=-

  class@class and@and virtual@virtual
  class-definition ::=   class class-binding { and class-binding }

     class-binding ::=   [virtual] [[ type-parameters ]] class-name  { pattern
                        } [: class-type] = class-expr
   type-parameters ::=   ' ident { , ' ident }

  A class definition class class-binding { and class-binding } is recursive.
Each class-binding defines a class-name that can be used in the whole
expression except for inheritance. It can also be used for inheritance, but
only in the definitions that follow its own.
  A class binding binds the class name class-name to the value of expression
class-expr. It also binds the class type class-name to the type of the class,
and defines two type abbreviations : class-name and # class-name. The first one
is the type of objects of this class, while the second is more general as it
unifies with the type of any object belonging to a subclass (see section
Section 5-4).
Virtual class
-------------

  virtual@virtual A class must be flagged virtual if one of its methods is
virtual (that is, appears in the class type, but is not actually defined).
Objects cannot be created from a virtual class.
Type parameters
---------------

  The class type parameters correspond to the ones of the class type and of the
two type abbreviations defined by the class binding. They must be bound to
actual types in the class definition using type constraints. So that the
abbreviations are well-formed, type variables of the inferred type of the class
must either be type parameters or be bound in the constraint clause.

5.9.4  Class specification
=-=-=-=-=-=-=-=-=-=-=-=-=-

  class@class and@and virtual@virtual
  class-specification ::=   class class-spec { and class-spec }

              class-spec ::=   [virtual] [[ type-parameters ]] class-name :
                                  class-type

  This is the counterpart in signatures of class definitions. A class
specification matches a class definition if they have the same type parameters
and their types match.

5.9.5  Class type definitions
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

  class@class type@type and@and virtual@virtual
  classtype-definition ::=   class type classtype-def  { and classtype-def }

            classtype-def ::=   [virtual] [[ type-parameters ]] class-name =
                               class-body-type

  A class type definition class class-name = class-body-type defines an
abbreviation class-name for the class body type class-body-type. As for class
definitions, two type abbreviations class-name and # class-name are also
defined. The definition can be parameterized by some type parameters. If any
method in the class type body is virtual, the definition must be flagged
virtual.
  Two class type definitions match if they have the same type parameters and
the types they expand to match.

5.10  Module types (module specifications)
==========================================

  Module types are the module-level equivalent of type expressions: they
specify the general shape and type properties of modules.
  sig@sig end@end functor@functor with@with val@val external@external type@type
exception@exception module@module open@open
     module-type ::=   modtype-path

                   |  sig { specification [;;] } end

                   |  functor ( module-name : module-type ) -> module-type

                   |  module-type with mod-constraint { and mod-constraint }

                   |  ( module-type )

   specification ::=   val value-name : typexpr

                   |  external value-name : typexpr = external-declaration

                   |  type-definition

                   |  exception-definition

                   |  class-specification

                   |  classtype-definition

                   |  module module-name : module-type

                    |  module module-name { ( module-name : module-type ) }  :
                                 module-type
                   |  module type modtype-name

                   |  module type modtype-name = module-type

                   |  open module-path

                   |  include modtype-path

  mod-constraint ::=   type [type-parameters] typeconstr = typexpr

                   |  module module-path = extended-module-path

5.10.1  Simple module types
=-=-=-=-=-=-=-=-=-=-=-=-=-=

  The expression modtype-path is equivalent to the module type bound to the
name modtype-path. The expression ( module-type ) denotes the same type as
module-type.

5.10.2  Signatures
=-=-=-=-=-=-=-=-=-

  sig@sig end@end
  Signatures are type specifications for structures. Signatures sig ... end are
collections of type specifications for value names, type names, exceptions,
module names and module type names. A structure will match a signature if the
structure provides definitions (implementations) for all the names specified in
the signature (and possibly more), and these definitions meet the type
requirements given in the signature.
  For compatibility with Caml Light, an optional ;; is allowed after each
specification in a signature. The ;; has no semantic meaning.
Value specifications
--------------------

  val@val
  A specification of a value component in a signature is written val value-name
: typexpr, where value-name is the name of the value and typexpr its expected
type.
  external@external
  The form external value-name : typexpr = external-declaration is similar,
except that it requires in addition the name to be implemented as the external
function specified in external-declaration (see chapter Chapter 15).
Type specifications
-------------------

  type@type
  A specification of one or several type components in a signature is written
type typedef { and typedef } and consists of a sequence of mutually recursive
definitions of type names.
  Each type definition in the signature specifies an optional type equation =
typexp and an optional type representation  = constr-decl ... or = { label-decl
... }. The implementation of the type name in a matching structure must be
compatible with the type expression specified in the equation (if given), and
have the specified representation (if given). Conversely, users of that
signature will be able to rely on the type equation or type representation, if
given. More precisely, we have the following four situations:

 Abstract type: no equation, no representation.
 Names that are defined as abstract types in a signature can be implemented in
   a matching structure by any kind of type definition (provided it has the
   same number of type parameters). The exact implementation of the type will
   be hidden to the users of the structure. In particular, if the type is
   implemented as a variant type or record type, the associated constructors
   and labels will not be accessible to the users; if the type is implemented
   as an abbreviation, the type equality between the type name and the
   right-hand side of the abbreviation will be hidden from the users of the
   structure. Users of the structure consider that type as incompatible with
   any other type: a fresh type has been generated.

 Type abbreviation: an equation = typexp, no representation.
 The type name must be implemented by a type compatible with typexp. All users
   of the structure know that the type name is compatible with typexp.

 New variant type or record type: no equation, a representation.
 The type name must be implemented by a variant type or record type with
   exactly the constructors or labels specified. All users of the structure
   have access to the constructors or labels, and can use them to create or
   inspect values of that type. However, users of the structure consider that
   type as incompatible with any other type: a fresh type has been generated.

 Re-exported variant type or record type: an equation, a representation.
 This case combines the previous two: the representation of the type is made
   visible to all users, and no fresh type is generated.

Exception specification
-----------------------

  exception@exception
  The specification exception constr-decl in a signature requires the matching
structure to provide an exception with the name and arguments specified in the
definition, and makes the exception available to all users of the structure.
Class specifications
--------------------

  A specification of one or several classes in a signature is written class
class-spec { and class-spec } and consists of a sequence of mutually recursive
definitions of class names.
  Class specifications are described more precisely in section
Subsection 5-9-4.
Class type specifications
-------------------------

  A specification of one or several classe types in a signature is written
class type classtype-def { and classtype-def } and consists of a sequence of
mutually recursive definitions of class type names. Class type specifications
are described more precisely in section Subsection 5-9-5.
Module specifications
---------------------

  module@module
  A specification of a module component in a signature is written module
module-name : module-type, where module-name is the name of the module
component and module-type its expected type. Modules can be nested arbitrarily;
in particular, functors can appear as components of structures and functor
types as components of signatures.
  For specifying a module component that is a functor, one may write
   module module-name ( name_1 : module-type_1 )  ... ( name_n : module-type_n
                               )  : module-type
   instead of
       module module-name :  functor ( name_1 : module-type_1 ) -> ...  ->
                                 module-type

Module type specifications
--------------------------

  type@type module@module
  A module type component of a signature can be specified either as a manifest
module type or as an abstract module type.
  An abstract module type specification module type modtype-name allows the
name modtype-name to be implemented by any module type in a matching signature,
but hides the implementation of the module type to all users of the signature.
  A manifest module type specification module type modtype-name = module-type
requires the name modtype-name to be implemented by the module type module-type
in a matching signature, but makes the equality between modtype-name and
module-type apparent to all users of the signature.
Opening a module path
---------------------

  open@open
  The expression open module-path in a signature does not specify any
components. It simply affects the parsing of the following items of the
signature, allowing components of the module denoted by module-path to be
referred to by their simple names name instead of path accesses module-path .
name. The scope of the open stops at the end of the signature expression.
Including a signature
---------------------

  include@include
  The expression include modtype-path in a signature performs textual inclusion
of the components of the signature denoted by modtype-path. It behaves as if
the components of the included signature were copied at the location of the
include. The modtype-path argument must refer to a module type that is a
signature,

5.10.3  Functor types
=-=-=-=-=-=-=-=-=-=-=

  functor@functor
  The module type expression  functor ( module-name : module-type_1 ) ->
module-type_2  is the type of functors (functions from modules to modules) that
take as argument a module of type module-type_1 and return as result a module
of type module-type_2. The module type module-type_2 can use the name
module-name to refer to type components of the actual argument of the functor.
No restrictions are placed on the type of the functor argument; in particular,
a functor may take another functor as argument (``higher-order'' functor).

5.10.4  The with operator
=-=-=-=-=-=-=-=-=-=-=-=-=

  with@with
  Assuming module-type denotes a signature, the expression module-type with
mod-constraint { and mod-constraint } denotes the same signature where type
equations have been added to some of the type specifications, as described by
the constraints following the with keyword. The constraint type
[type-parameters] typeconstr = typexp  adds the type equation = typexp to the
specification of the type component named typeconstr of the constrained
signature. The constraint module module-path = extended-module-path adds type
equations to all type components of the sub-structure denoted by module-path,
making them equivalent to the corresponding type components of the structure
denoted by extended-module-path.
  For instance, if the module type name S is bound to the signature
<<
          sig type t module M: (sig type u end) end
>>
   then S with type t=int denotes the signature
<<
          sig type t=int module M: (sig type u end) end
>>
   and S with module M = N denotes the signature
<<
          sig type t module M: (sig type u=N.u end) end
>>
   A functor taking two arguments of type S that share their t component is
written
<<
          functor (A: S) (B: S with type t = A.t) ...
>>

5.11  Module expressions (module implementations)
=================================================

  Module expressions are the module-level equivalent of value expressions: they
evaluate to modules, thus providing implementations for the specifications
expressed in module types.
  struct@struct end@end functor@functor let@let external@external type@type
exception@exception module@module open@open
  module-expr ::=   module-path

                |  struct { definition [;;] } end

                |  functor ( module-name : module-type ) -> module-expr

                |  module-expr ( module-expr )

                |  ( module-expr )

                |  ( module-expr : module-type )

   definition ::=   let [rec] let-binding { and let-binding }

                |  external value-name : typexpr = external-declaration

                |  type-definition

                |  exception-definition

                |  class-definition

                |  classtype-definition

                 |  module module-name { ( module-name : module-type ) }  [ :
                         module-type ] = module-expr
                |  module type modtype-name = module-type

                |  open module-path

5.11.1  Simple module expressions
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

  The expression module-path evaluates to the module bound to the name
module-path.
  The expression ( module-expr ) evaluates to the same module as module-expr.
  The expression ( module-expr : module-type ) checks that the type of
module-expr is a subtype of module-type, that is, that all components specified
in module-type are implemented in module-expr, and their implementation meets
the requirements given in module-type. In other terms, it checks that the
implementation module-expr meets the type specification module-type. The whole
expression evaluates to the same module as module-expr, except that all
components not specified in module-type are hidden and can no longer be
accessed.

5.11.2  Structures
=-=-=-=-=-=-=-=-=-

  struct@struct end@end
  Structures struct ... end are collections of definitions for value names,
type names, exceptions, module names and module type names. The definitions are
evaluated in the order in which they appear in the structure. The scope of the
bindings performed by the definitions extend to the end of the structure. As a
consequence, a definition may refer to names bound by earlier definitions in
the same structure.
  For compatibility with toplevel phrases (chapter Chapter 8)
and with Caml Light, an optional ;; is allowed after each definition in a
structure. The ;; has no semantic meaning. Also for compatibility, ;; expr is
allowed as a component of a structure, meaning let _ = expr, i.e. evaluate expr
for its side-effects.
Value definitions
-----------------

  let@let
  A value definition let [rec] let-binding { and let-binding } bind value names
in the same way as a let ... in ... expression (see section
Subsection 5-7-1). The value names appearing in the left-hand sides of
the bindings are bound to the corresponding values in the right-hand sides.
  external@external
  A value definition external value-name : typexpr = external-declaration
implements value-name as the external function specified in
external-declaration (see chapter Chapter 15).
Type definitions
----------------

  type@type
  A definition of one or several type components is written type typedef { and
typedef } and consists of a sequence of mutually recursive definitions of type
names.
Exception definitions
---------------------

  exception@exception
  Exceptions are defined with the syntax exception constr-decl.
Class definitions
-----------------

  A definition of one or several classes is written class class-binding { and
class-binding } and consists of a sequence of mutually recursive definitions of
class names. Class definitions are described more precisely in section
Subsection 5-9-3.
Class type definitions
----------------------

  A definition of one or several classes is written class type classtype-def {
and classtype-def } and consists of a sequence of mutually recursive
definitions of class type names. Class type definitions are described more
precisely in section Subsection 5-9-5.
Module definitions
------------------

  module@module
  The basic form for defining a module component is module module-name =
module-expr, which evaluates module-expr and binds the result to the name
module-name.
  One can write
                 module module-name : module-type = module-expr
   instead of
               module module-name = ( module-expr : module-type ).
   Another derived form is
   module module-name ( name_1 : module-type_1 ) ...  ( name_n : module-type_n
                               ) = module-expr
   which is equivalent to
       module module-name =  functor ( name_1 : module-type_1 ) -> ...  ->
                                 module-expr

Module type definitions
-----------------------

  type@type module@module
  A definition for a module type is written module type modtype-name =
module-type. It binds the name modtype-name to the module type denoted by the
expression module-type.
Opening a module path
---------------------

  open@open
  The expression open module-path in a structure does not define any components
nor perform any bindings. It simply affects the parsing of the following items
of the structure, allowing components of the module denoted by module-path to
be referred to by their simple names name instead of path accesses module-path
. name. The scope of the open stops at the end of the structure expression.

5.11.3  Functors
=-=-=-=-=-=-=-=-

Functor definition
------------------

  functor@functor
  The expression functor ( module-name : module-type ) -> module-expr evaluates
to a functor that takes as argument modules of the type module-type_1, binds
module-name to these modules, evaluates module-expr in the extended
environment, and returns the resulting modules as results. No restrictions are
placed on the type of the functor argument; in particular, a functor may take
another functor as argument (``higher-order'' functor).
Functor application
-------------------

  The expression module-expr_1 ( module-expr_2 ) evaluates module-expr_1 to a
functor and module-expr_2 to a module, and applies the former to the latter.
The type of module-expr_2 must match the type expected for the arguments of the
functor module-expr_1.

5.12  Compilation units
=======================

                     unit-interface ::=  { specification [;;] }
                unit-implementation ::=  { definition [;;] }

  Compilation units bridge the module system and the separate compilation
system. A compilation unit is composed of two parts: an interface and an
implementation. The interface contains a sequence of specifications, just as
the inside of a sig ... end signature expression. The implementation contains a
sequence of definitions, just as the inside of a struct ... end module
expression. A compilation unit also has a name unit-name, derived from the
names of the files containing the interface and the implementation (see chapter
Chapter 7 for more details). A compilation unit behaves roughly as
the module definition
   module unit-name : sig unit-interface end =  struct unit-implementation end

  A compilation unit can refer to other compilation units by their names, as if
they were regular modules. For instance, if U is a compilation unit that
defines a type t, other compilation units can refer to that type under the name
U.t; they can also refer to U as a whole structure. Except for names of other
compilation units, a unit interface or unit implementation must not have any
other free variables. In other terms, the type-checking and compilation of an
interface or implementation proceeds in the initial environment
         name_1 : sig interface_1 end ...  name_n : sig interface_n end
   where name_1 ... name_N are the names of the other compilation units
available in the search path (see chapter Chapter 7 for more
details) and interface_1 ... interface_n are their respective interfaces.

Chapter 6    Language extensions
********************************

  This chapter describes the language features that are implemented in
Objective Caml, but not described in the Objective Caml reference manual. In
contrast with the fairly stable kernel language that is described in the
reference manual, the extensions presented here are still experimental, and may
be removed or changed in the future.

6.1  Streams and stream parsers
===============================

  Objective Caml comprises a library type for streams (possibly infinite
sequences of elements, that are evaluated on demand), and associated stream
expressions, to build streams, and stream patterns, to destructure streams.
Streams and stream patterns provide a natural approach to the writing of
recursive-descent parsers.
  Streams are presented by the following extensions to the syntactic classes of
expressions:
  parser@parser match@match match@when
              expr ::=   ...

                     |  [< >]

                     |  [< stream-component { ; stream-component } >]

                     |  parser [pattern] stream-matching

                     |  match expr with parser [pattern] stream-matching

  stream-component ::=   ' expr

                     |  expr

    stream-matching ::=   stream-pattern [pattern] -> expr  { | stream-pattern
                             [pattern] -> expr }
    stream-pattern ::=   [< >]

                     |  [< stream-pat-comp { ; stream-pat-comp [ ? expr ] }>]

   stream-pat-comp ::=   ' pattern [ when expr ]

                     |  pattern = expr

                     |  ident

  Stream expressions are bracketed by `[<' and `>]'. They represent the
concatenation of their components. The component ' expr represents the
one-element stream whose element is the value of expr. The component expr
represents a sub-stream. For instance, if both s and t are streams of integers,
then `[<'1; s; t; '2>]' is a stream of integers containing the element 1, then
the elements of s, then those of t, and finally 2. The empty stream is denoted
by `[< >]'.
  Unlike any other kind of expressions in the language, stream expressions are
submitted to lazy evaluation: the components are not evaluated when the stream
is built, but only when they are accessed during stream matching. The
components are evaluated once, the first time they are accessed; the following
accesses reuse the value computed the first time.
  Stream patterns, also bracketed by `[<' and `>]', describe initial segments
of streams. In particular, the stream pattern `[< >]' matches all streams.
Stream pattern components are matched against the corresponding elements of a
stream. The component ' pattern matches the corresponding stream element
against the pattern; if followed by when, the match is accepted only if the
result of the guard expression is true. The component pattern = expr applies
the function denoted by expr to the current stream, then matches the result of
the function against pattern. Finally, the component ident simply binds the
identifier to the stream being matched.
  Stream matching proceeds destructively: once a component has been matched, it
is discarded from the stream (by in-place modification).
  Stream matching proceeds in two steps: first, a pattern is selected by
matching the stream against the first components of the stream patterns; then,
the following components of the selected pattern are checked against the
stream. If the following components do not match, the exception Stream.Error is
raised. There is no backtracking here: stream matching commits to the pattern
selected according to the first element. If none of the first components of the
stream patterns match, the exception Stream.Failure is raised. The
Stream.Parse_failure exception causes the next alternative to be tried, if it
occurs during the matching of the first element of a stream, before matching
has committed to one pattern.
  The streams hold the count of their elements discarded. The optional pattern
before the first stream pattern is bound to the stream count before the
matching. The one after each stream pattern (optional, too) is bound to the
stream count after the matching.
  The exception Parse_error has a string parameter coming from the optional ?
expr after the stream pattern components (its default is the empty string).
This expression is evaluated only in case of error.
  See Functional programming using Caml Light for a more gentle introductions
to streams, and for some examples of their use in writing parsers. A more
formal presentation of streams, and a discussion of alternate semantics, can be
found in Parsers in ML by Michel Mauny and Daniel de Rauglaudre, in the
proceedings of the 1992 ACM conference on Lisp and Functional Programming.

6.2  Range patterns
===================

  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.

6.3  Assertion checking
=======================
   assert@assert
  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).
Assert_failure (exception)@`Assert_failure' (exception)

6.4  Deferred computations
==========================
   lazy@lazy
  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.
  The expression lazy expr is equivalent to ref(Lazy.Delayed(fun () -> expr)).
For more information, see the description of module Lazy in the standard
library (section Section 17-12). Lazy (module)@`Lazy'
(module)force@`force'

6.5  Record copy with update
============================
   with@with
  The expression { expr with lbl_1 = expr_1 ; ... ; lbl_n = expr_n } builds a
fresh record with fields lbl_1 ... lbl_n equal to expr_1 ... expr_n, and all
other fields having the same value as in the record expr. In other terms, it
returns a shallow copy of the record expr, except for the fields lbl_1 ...
lbl_n, which are initialized to expr_1 ... expr_n. For example:
<<
          type point = { x : float; y : float; z : float }
          let proj p = { p with x = 0.0 }
          let proj p = { x = 0.0; y = p.y; z = p.z }
>>
   The two definitions of proj above are equivalent.

6.6  Local modules
==================
   let@let module@module
  The expression let module module-name = module-expr in expr locally binds the
module expression module-expr to the identifier module-name 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)
>>

                                   Part: III
                                   #########
                           The Objective Caml tools
                           ########################

Chapter 7    Batch compilation (ocamlc)
***************************************

  This chapter describes the Objective Caml batch compiler ocamlc, which
compiles Caml source files to bytecode object files and link these object files
to produce standalone bytecode executable files. These executable files are
then run by the bytecode interpreter ocamlrun.