The table below shows the relative precedences and associativity of operators and nonclosed constructions. The constructions with higher precedence come first. For infix and prefix symbols, we write “*…” to mean “any symbol starting with *”.
Construction or operator  Associativity 
prefixsymbol  – 
. .( .[  – 
function application, constructor application, assert, lazy  left 
 . (prefix)  – 
**… lsl lsr asr  right 
*… /… %… mod land lor lxor  left 
+… …  left 
::  right 
@… ^…  right 
=… <… >… … &… $…  left 
& &&  right 
or   right 
,  – 
< :=  right 
if  – 
;  right 
let match fun function try  – 
Expressions consisting in a constant evaluate to this constant.
Expressions consisting in an access path evaluate to the value bound to this path in the current evaluation environment. The path can be either a value name or an access path to a value component of a module.
The expressions ( expr ) and begin expr end have the same value as expr. Both constructs are semantically equivalent, but it is good style to use begin … end inside control structures:
if … then begin … ; … end else begin … ; … end
and ( … ) for the other grouping situations.
Parenthesized expressions can contain a type constraint, as in ( expr : typexpr ). This constraint forces the type of expr to be compatible with typexpr.
Parenthesized expressions can also contain coercions ( expr [: typexpr] :> typexpr) (see subsection 6.7.6 below).
Function application is denoted by juxtaposition of (possibly labeled) expressions. The expression expr argument_{1} … argument_{n} evaluates the expression expr and those appearing in argument_{1} to argument_{n}. The expression expr must evaluate to a functional value f, which is then applied to the values of argument_{1}, …, argument_{n}.
The order in which the expressions expr, argument_{1}, …, argument_{n} are evaluated is not specified.
Arguments and parameters are matched according to their respective labels. Argument order is irrelevant, except among arguments with the same label, or no label.
If a parameter is specified as optional (label prefixed by ?) in the type of expr, the corresponding argument will be automatically wrapped with the constructor Some, except if the argument itself is also prefixed by ?, in which case it is passed as is. If a nonlabeled argument is passed, and its corresponding parameter is preceded by one or several optional parameters, then these parameters are defaulted, i.e. the value None will be passed for them. All other missing parameters (without corresponding argument), both optional and nonoptional, will be kept, and the result of the function will still be a function of these missing parameters to the body of f.
As a special case, if the function has a known arity, all the arguments are unlabeled, and their number matches the number of nonoptional parameters, then labels are ignored and nonoptional parameters are matched in their definition order. Optional arguments are defaulted.
In all cases but exact match of order and labels, without optional parameters, the function type should be known at the application point. This can be ensured by adding a type constraint. Principality of the derivation can be checked in the principal mode.
Two syntactic forms are provided to define functions. The first form is introduced by the keyword function:

This expression evaluates to a functional value with one argument. When this function is applied to a value v, this value is matched against each pattern pattern_{1} to pattern_{n}. If one of these matchings succeeds, that is, if the value v matches the pattern pattern_{i} for some i, then the expression expr_{i} associated to the selected pattern is evaluated, and its value becomes the value of the function application. The evaluation of expr_{i} takes place in an environment enriched by the bindings performed during the matching.
If several patterns match the argument v, the one that occurs first in the function definition is selected. If none of the patterns matches the argument, the exception Match_failure is raised.
The other form of function definition is introduced by the keyword fun:
This expression is equivalent to:
The parameter patterns ~var and ~(var [: typexpr]) are shorthands for respectively ~var:var and ~var:(var [: typexpr]), and similarly for their optional counterparts.
Functions of the form fun ?lab:( pattern = expr_{0} ) > expr are equivalent to
where ident is a fresh variable. When expr_{0} will be evaluated is left unspecified.
After these two transformations, expressions are of the form
If we ignore labels, which will only be meaningful at function application, this is equivalent to
That is, the fun expression above evaluates to a curried function with n arguments: after applying this function n times to the values v_{1} … v_{m}, the values will be matched in parallel against the patterns pattern_{1} … pattern_{n}. If the matching succeeds, the function returns the value of expr in an environment enriched by the bindings performed during the matchings. If the matching fails, the exception Match_failure is raised.
Cases of a pattern matching (in the function, fun, match and try constructs) can include guard expressions, which are arbitrary boolean expressions that must evaluate to true for the match case to be selected. Guards occur just before the > token and are introduced by the when keyword:

Matching proceeds as described before, except that if the value matches some pattern pattern_{i} which has a guard cond_{i}, then the expression cond_{i} is evaluated (in an environment enriched by the bindings performed during matching). If cond_{i} evaluates to true, then expr_{i} is evaluated and its value returned as the result of the matching, as usual. But if cond_{i} evaluates to false, the matching is resumed against the patterns following pattern_{i}.
The let and let rec constructs bind value names locally. The construct
evaluates expr_{1} … expr_{n} in some unspecified order, then matches their values against the patterns pattern_{1} … pattern_{n}. If the matchings succeed, expr is evaluated in the environment enriched by the bindings performed during matching, and the value of expr is returned as the value of the whole let expression. If one of the matchings fails, the exception Match_failure is raised.
An alternate syntax is provided to bind variables to functional values: instead of writing
in a let expression, one may instead write
Recursive definitions of names are introduced by let rec:
The only difference with the let construct described above is that the bindings of names to values performed by the patternmatching are considered already performed when the expressions expr_{1} to expr_{n} are evaluated. That is, the expressions expr_{1} to expr_{n} can reference identifiers that are bound by one of the patterns pattern_{1}, …, pattern_{n}, and expect them to have the same value as in expr, the body of the let rec construct.
The recursive definition is guaranteed to behave as described above if the expressions expr_{1} to expr_{n} are function definitions (fun … or function …), and the patterns pattern_{1} … pattern_{n} are just value names, as in:
This defines name_{1} … name_{n} as mutually recursive functions local to expr.
The behavior of other forms of let rec definitions is implementationdependent. The current implementation also supports a certain class of recursive definitions of nonfunctional values, as explained in section 7.3.
The expression expr_{1} ; expr_{2} evaluates expr_{1} first, then expr_{2}, and returns the value of expr_{2}.
The expression if expr_{1} then expr_{2} else expr_{3} evaluates to the value of expr_{2} if expr_{1} evaluates to the boolean true, and to the value of expr_{3} if expr_{1} evaluates to the boolean false.
The else expr_{3} part can be omitted, in which case it defaults to else ().
The expression

matches the value of expr against the patterns pattern_{1} to pattern_{n}. If the matching against pattern_{i} succeeds, the associated expression expr_{i} is evaluated, and its value becomes the value of the whole match expression. The evaluation of expr_{i} takes place in an environment enriched by the bindings performed during matching. If several patterns match the value of expr, the one that occurs first in the match expression is selected. If none of the patterns match the value of expr, the exception Match_failure is raised.
The expression expr_{1} && expr_{2} evaluates to true if both expr_{1} and expr_{2} evaluate to true; otherwise, it evaluates to false. The first component, expr_{1}, is evaluated first. The second component, expr_{2}, is not evaluated if the first component evaluates to false. Hence, the expression expr_{1} && expr_{2} behaves exactly as
The expression expr_{1}  expr_{2} evaluates to true if one of expr_{1} and expr_{2} evaluates to true; otherwise, it evaluates to false. The first component, expr_{1}, is evaluated first. The second component, expr_{2}, is not evaluated if the first component evaluates to true. Hence, the expression expr_{1}  expr_{2} behaves exactly as
The boolean operator & is synonymous for &&. The boolean operator or is synonymous for .
The expression while expr_{1} do expr_{2} done repeatedly evaluates expr_{2} while expr_{1} evaluates to true. The loop condition expr_{1} is evaluated and tested at the beginning of each iteration. The whole while … done expression evaluates to the unit value ().
The expression for name = expr_{1} to expr_{2} do expr_{3} done first evaluates the expressions expr_{1} and expr_{2} (the boundaries) into integer values n and p. Then, the loop body expr_{3} is repeatedly evaluated in an environment where name is successively bound to the values n, n+1, …, p−1, p. The loop body is never evaluated if n > p.
The expression for name = expr_{1} downto expr_{2} do expr_{3} done evaluates similarly, except that name is successively bound to the values n, n−1, …, p+1, p. The loop body is never evaluated if n < p.
In both cases, the whole for expression evaluates to the unit value ().
The expression

evaluates the expression expr and returns its value if the evaluation of expr does not raise any exception. If the evaluation of expr raises an exception, the exception value is matched against the patterns pattern_{1} to pattern_{n}. If the matching against pattern_{i} succeeds, the associated expression expr_{i} is evaluated, and its value becomes the value of the whole try expression. The evaluation of expr_{i} takes place in an environment enriched by the bindings performed during matching. If several patterns match the value of expr, the one that occurs first in the try expression is selected. If none of the patterns matches the value of expr, the exception value is raised again, thereby transparently “passing through” the try construct.
The expression expr_{1} , … , expr_{n} evaluates to the ntuple of the values of expressions expr_{1} to expr_{n}. The evaluation order for the subexpressions is not specified.
The expression constr expr evaluates to the variant value whose constructor is constr, and whose argument is the value of expr.
For lists, some syntactic sugar is provided. The expression expr_{1} :: expr_{2} stands for the constructor ( :: ) applied to the argument ( expr_{1} , expr_{2} ), and therefore evaluates to the list whose head is the value of expr_{1} and whose tail is the value of expr_{2}. The expression [ expr_{1} ; … ; expr_{n} ] is equivalent to expr_{1} :: … :: expr_{n} :: [], and therefore evaluates to the list whose elements are the values of expr_{1} to expr_{n}.
The expression `tagname expr evaluates to the polymorphic variant value whose tag is tagname, and whose argument is the value of expr.
The expression { field_{1} = expr_{1} ; … ; field_{n} = expr_{n} } evaluates to the record value { field_{1} = v_{1}; …; field_{n} = v_{n} } where v_{i} is the value of expr_{i} for i = 1,… , n. The fields field_{1} to field_{n} must all belong to the same record types; all fields belonging to this record type must appear exactly once in the record expression, though they can appear in any order. The order in which expr_{1} to expr_{n} are evaluated is not specified.
The expression { expr with field_{1} = expr_{1} ; … ; field_{n} = expr_{n} } builds a fresh record with fields field_{1} … field_{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 field_{1} … field_{n}, which are initialized to expr_{1} … expr_{n}.
The expression expr_{1} . field evaluates expr_{1} to a record value, and returns the value associated to field in this record value.
The expression expr_{1} . field < expr_{2} evaluates expr_{1} to a record value, which is then modified inplace by replacing the value associated to field in this record by the value of expr_{2}. This operation is permitted only if field has been declared mutable in the definition of the record type. The whole expression expr_{1} . field < expr_{2} evaluates to the unit value ().
The expression [ expr_{1} ; … ; expr_{n} ] evaluates to a nelement array, whose elements are initialized with the values of expr_{1} to expr_{n} respectively. The order in which these expressions are evaluated is unspecified.
The expression expr_{1} .( expr_{2} ) returns the value of element number expr_{2} in the array denoted by expr_{1}. The first element has number 0; the last element has number n−1, where n is the size of the array. The exception Invalid_argument is raised if the access is out of bounds.
The expression expr_{1} .( expr_{2} ) < expr_{3} modifies inplace the array denoted by expr_{1}, replacing element number expr_{2} by the value of expr_{3}. The exception Invalid_argument is raised if the access is out of bounds. The value of the whole expression is ().
The expression expr_{1} .[ expr_{2} ] returns the value of character number expr_{2} in the string denoted by expr_{1}. The first character has number 0; the last character has number n−1, where n is the length of the string. The exception Invalid_argument is raised if the access is out of bounds.
The expression expr_{1} .[ expr_{2} ] < expr_{3} modifies inplace the string denoted by expr_{1}, replacing character number expr_{2} by the value of expr_{3}. The exception Invalid_argument is raised if the access is out of bounds. The value of the whole expression is ().
Symbols from the class infixsymbols, as well as the keywords *, =, or and &, can appear in infix position (between two expressions). Symbols from the class prefixsymbols 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 prefixsymbol expr is interpreted as the application ( prefixsymbol ) expr. Similarly, the expression expr_{1} infixsymbol expr_{2} is interpreted as the application ( infixsymbol ) expr_{1} expr_{2}.
The table below lists the symbols defined in the initial environment and their initial meaning. (See the description of the core library module Pervasives in chapter 19 for more details). Their meaning may be changed at any time using let ( infixop ) 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. 
mod  Integer modulus. Raise Division_by_zero if second argument is zero. 
land  Bitwise logical “and” on integers. 
lor  Bitwise logical “or” on integers. 
lxor  Bitwise logical “exclusive or” on integers. 
lsl  Bitwise logical shift left on integers. 
lsr  Bitwise logical shift right on integers. 
asr  Bitwise arithmetic shift right on integers. 
+.  Floatingpoint addition. 
. (infix)  Floatingpoint subtraction. 
. (prefix)  Floatingpoint negation. 
*.  Floatingpoint multiplication. 
/.  Floatingpoint division. 
**  Floatingpoint 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”. 
When classpath evaluates to a class body, new classpath evaluates to an object containing the instance variables and methods of this class.
When classpath evaluates to a class function, new classpath evaluates to a function expecting the same number of arguments and returning a new object of this class.
Creating directly an object through the object classbody end construct is operationally equivalent to defining locally a class classname = object classbody end —see sections 6.9.2 and following for the syntax of classbody— and immediately creating a single object from it by new classname.
The typing of immediate objects is slightly different from explicitely defining a class in two respects. First, the inferred object type may contain free type variables. Second, since the class body of an immediate object will never be extended, its self type can be unified with a closed object type.
The expression expr # methodname invokes the method methodname of the object denoted by expr.
If methodname is a polymorphic method, its type should be known at the invocation site. This is true for instance if expr is the name of a fresh object (let ident = new classpath … ) or if there is a type constraint. Principality of the derivation can be checked in the principal mode.
The instance variables of a class are visible only in the body of the methods defined in the same class or a class that inherits from the class defining the instance variables. The expression instvarname evaluates to the value of the given instance variable. The expression instvarname < expr assigns the value of expr to the instance variable instvarname, which must be mutable. The whole expression instvarname < expr evaluates to ().
An object can be duplicated using the library function Oo.copy (see Module Oo). Inside a method, the expression {< instvarname = expr { ; instvarname = 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.
Expressions whose type contains object or polymorphic variant types can be explicitly 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 the current implementation it only expands two levels of type abbreviations containing objects and/or polymorphic variants, keeping only recursion when it is explicit in the class type (for objects). As an exception to the above algorithm, if both the inferred type of expr and typexpr are ground (i.e. do not contain type variables), the former operator behaves as the latter one, taking the inferred type of expr as typexpr_{1}. In case of failure with the former operator, the latter one should be used.
It is only possible to coerce an expression expr from type typexpr_{1} to type typexpr_{2}, if the type of expr is an instance of typexpr_{1} (like for a type annotation), and typexpr_{1} is a subtype of typexpr_{2}. The type of the coerced expression is an instance of typexpr_{2}. If the types contain variables, they may be instanciated by the subtyping algorithm, but this is only done after determining whether typexpr_{1} is a potential subtype of typexpr_{2}. This means that typing may fail during this latter unification step, even if some instance of typexpr_{1} is a subtype of some instance of typexpr_{2}. In the following paragraphs we describe the subtyping relation used.
A fixed object type admits as subtype any object type including all its methods. The types of the methods shall be subtypes of those in the supertype. Namely,
< met_{1} : typ_{1} ; ... ; met_{n} : typ_{n} > 
is a supertype of
< met_{1} : typ′_{1} ; ... ; met_{n} : typ′_{n} ; met_{n+1} : typ′_{n+1} ; ... ; met_{n+m} : typ′_{n+m} [ ; ..] > 
which may contain an ellipsis .., if every typ_{i} is a supertype of typ′_{i}.
A monomorphic method type can be a supertype of a polymorphic method type. Namely, if typ is an instance of typ′, then ′a_{1} ... ′a_{n} .typ′ is a subtype of typ.
Inside a class definition, newly defined types are not available for subtyping, as the type abbreviations are not yet completely defined. There is an exception for coercing self to the (exact) type of its class: this is allowed if the type of self does not appear in a contravariant position in the class type, i.e. if there are no binary methods.
A polymorphic variant type typ is subtype of another polymorphic variant type typ′ if the upper bound of typ (i.e. the maximum set of constructors that may appear in an instance of typ) is included in the lower bound of typ′, and the types of arguments for the constructors of typ are subtypes of those in typ′. Namely,
[[ <] ′C_{1} of typ_{1}  ...  ′C_{n} of typ_{n} ] 
which may be a shrinkable type, is a subtype of
[[ >] ′C_{1} of typ′_{1}  ...  ′C_{n} of typ′_{n}  ′C_{n+1} of typ′_{n+1}  ...  ′C_{n+m} of typ′_{n+m} ] 
which may be an extensible type, if every typ_{i} is a subtype of typ′_{i}.
Other types do not introduce new subtyping, but they may propagate the subtyping of their arguments. For instance, typ_{1} * typ_{2} is a subtype of typ′_{1} * typ′_{2} when typ_{1} and typ_{2} are respectively subtypes of typ′_{1} and typ′_{2}. For function types, the relation is more subtle: typ_{1} > typ_{2} is a subtype of typ′_{1} > typ′_{2} if typ_{1} is a supertype of typ′_{1} and typ_{2} is a subtype of typ′_{2}. For this reason, function types are covariant in their second argument (like tuples), but contravariant in their first argument. Mutable types, like array or ref are neither covariant nor contravariant, they are nonvariant, that is they do not propagate subtyping.
For user defined types, the variance is automatically inferred: a parameter is covariant if it has only covariant occurences, contravariant if it has only contravariant occurences, variancefree if it has no occurences, and nonvariant otherwise. A variancefree parameter may change freely through subtyping, it does not have to be a subtype or a supertype. For abstract and private types, the variance must be given explicitly, otherwise the default is nonvariant. This is also the case for constrained arguments in type definitions.