expr:ident|variable|constant|`(`

expr`)`

|`begin`

expr`end`

|`(`

expr`:`

typexpr`)`

|expr`,`

expr{`,`

expr}|ncconstrexpr|expr`::`

expr|`[`

expr{`;`

expr}`]`

|`[|`

expr{`;`

expr}`|]`

|`{`

label`=`

expr{`;`

label`=`

expr}`}`

|exprexpr|prefix-opexpr|exprinfix-opexpr|expr`.`

label|expr`.`

label`<-`

expr|expr`.(`

expr`)`

|expr`.(`

expr`)`

`<-`

expr|expr`&`

expr|expr`or`

expr|`if`

expr`then`

expr[`else`

expr]|`while`

expr`do`

expr`done`

|`for`

ident`=`

expr(`to`

|`downto`

)expr`do`

expr`done`

|expr`;`

expr|`match`

expr`with`

simple-matching|`fun`

multiple-matching|`function`

simple-matching|`try`

expr`with`

simple-matching|`let`

[`rec`

]let-binding{`and`

let-binding}`in`

exprsimple-matching:pattern`->`

expr{`|`

pattern`->`

expr}multiple-matching:pattern-list`->`

expr{`|`

pattern-list`->`

expr}pattern-list:pattern{pattern}let-binding:pattern`=`

expr|variablepattern-list`=`

exprprefix-op:`-`

|`-.`

|`!`

infix-op:`+`

|`-`

|`*`

|`/`

|`mod`

|`+.`

|`-.`

|`*.`

|`/.`

|`**`

|`@`

|`^`

|`!`

|`:=`

|`=`

|`<>`

|`==`

|`!=`

|`<`

|`<=`

|`>`

|`>=`

|`<.`

|`<=.`

|`>.`

|`>=.`

The table below shows the relative precedences and associativity of operators and non-closed constructions. The constructions with higher precedence come first.

Construction or operator | Associativity |
---|---|

! | -- |

. .( | -- |

function application | left |

constructor application | -- |

- -. (prefix) | -- |

** | right |

mod | left |

* *. / /. | left |

+ +. - -. | left |

:: | right |

@ ^ | right |

comparisons (= == < etc.) | left |

not | -- |

& | left |

or | left |

, | -- |

<- := | right |

if | -- |

; | right |

let match fun function try | -- |

Expressions consisting in a constant evaluate to this constant.

Expressions consisting in a variable evaluate to the value bound to this variable in the current evaluation environment. The variable can be either a qualified identifier or a simple identifier. Qualified identifiers always denote global variables. Simple identifiers denote either a local variable, if the identifier is locally bound, or a global variable, whose full name is obtained by qualifying the simple identifier, as described in section 3.3.

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 ... ; ... endand

`(`

...`)`

for the other grouping situations.
Parenthesized expressions can contain a type constraint, as in `(`

*expr* `:`

*type* `)`

. This constraint forces the type of *expr* to be
compatible with *type*.

The most general form of function abstraction is:

funThis expression evaluates to a functional value withpattern11 ...pattern1M ->expr1 | ... |patternN1 ...patternNM ->exprN

If several pattern rows match the arguments, the one that occurs first
in the function definition is selected. If none of the pattern rows
matches the argument, the exception `Match_failure` is raised.

If the function above is applied to less than *m* arguments, a
functional value is returned, that represents the partial application
of the function to the arguments provided. This partial application is
a function that, when applied to the remaining arguments,
matches all arguments against the pattern rows as described above.
Matching does not start until all *m* arguments have been provided
to the function; hence, partial applications of the function to less
than *m* arguments never raise `Match_failure`.

All pattern rows in the function body must contain the same number of patterns. A variable must not be bound more than once in one pattern row.

Functions with only one argument can be defined with the
`function` keyword instead of `fun`:

functionThe function thus defined behaves exactly as described above. The only difference between the two forms of function definition is how a parsing ambiguity is resolved. The two formspattern1 ->expr1 | ... |patternN ->exprN

Function application is denoted by juxtaposition of expressions. The
expression *expr*_{1} *expr*_{2}...*expr*_{n} evaluates the expressions
*expr*_{1} to *expr*_{n}. The expression *expr*_{1} must evaluate to a
functional value, which is then applied to the values of
*expr*_{2},...,*expr*_{n}. The order in which the expressions *expr*_{1},...,*expr*_{n} are evaluated is not specified.

The `let` and `let rec` constructs bind variables locally.
The construct

evaluates`let`

pattern_{1}`=`

expr_{1}`and`

...`and`

pattern_{n}`=`

expr_{n}`in`

expr

An alternate syntax is provided to bind variables to functional values: instead of writing

in aident`=`

`fun`

pattern_{1}...pattern_{m}`->`

expr

Both forms bindidentpattern_{1}...pattern_{m}`=`

expr

pattern_{1}...pattern_{m}`->`

expr.

Recursive definitions of variables are introduced by `let rec`:

The only difference with the`let`

`rec`

pattern_{1}`=`

expr_{1}`and`

...`and`

pattern_{n}`=`

expr_{n}`in`

expr

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} consist in a single variable, as in:

This defines`let`

`rec`

ident_{1}`=`

`fun`

...`and`

...`and`

ident_{n}`=`

`fun`

...`in`

expr

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

matchmatches the value ofexprwithpattern1 ->expr1 | ... |patternN ->exprN

`match`

expression. The evaluation of
`match`

expression is
selected. If none of the patterns match the value of `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

`if`

expr_{1}`then`

expr_{2}`else`

`false`

.

The expression *expr*_{1} `or`

*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} `or`

*expr*_{2} behaves
exactly as

`if`

expr_{1}`then`

`true`

`else`

expr_{2}.

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`

*ident* `=`

*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 the local variable named
*ident* is successively bound to the values
*n*, *n*+1, \ldots, *p*-1, *p*.
The loop body is never evaluated if *n* > *p*.

The expression `for`

*ident* `=`

*expr*_{1} `downto`

*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 the local variable named
*ident* is successively bound to the values
*n*, *n*-1, \ldots, *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

tryevaluates the expressionexprwithpattern1 ->expr1 | ... |patternN ->exprN

`try`

expression. The
evaluation of `try`

expression is
selected. If none of the patterns matches the value of `try`

construct.

The expression *expr*_{1} `,`

...`,`

*expr*_{n} evaluates to the
*n*-tuple of the values of expressions *expr*_{1} to *expr*_{n}. The
evaluation order for the subexpressions is not specified.

The expression *ncconstr* *expr* evaluates to the variant value whose
constructor is *ncconstr*, 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 `prefix`

`::`

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 `{`

*label*_{1} `=`

*expr*_{1} `;`

...`;`

*label*_{n} `=`

*expr*_{n} `}`

evaluates to the record value
`{`

*label*_{1} `=`

*v*_{1} `;`

...`;`

*label*_{n} `=`

*v*_{n} `}`

,
where *v*_{i} is the value of *expr*_{i} for *i* = 1, ..., *n*.
The labels *label*_{1} to *label*_{n} must all belong to the same record
types; all labels 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*_{1} `.`

*label* evaluates *expr*_{1} to a record
value, and returns the value associated to *label* in this record
value.

The expression *expr*_{1} `.`

*label* `<-`

*expr*_{2} evaluates *expr*_{1} to a record
value, which is then modified in-place by replacing the value
associated to *label* in this record by the value of
*expr*_{2}. This operation is permitted only if *label* has been
declared `mutable`

in the definition of the record type. The whole
expression *expr*_{1} `.`

*label* `<-`

*expr*_{2} evaluates to the unit value
`()`

.

The expression `[|`

*expr*_{1} `;`

...`;`

*expr*_{n} `|]`

evaluates to
a *n*-element 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} `)`

is equivalent to the
application `vect_item`

*expr*_{1} *expr*_{2}. In the initial environment,
the identifier `vect_item`

resolves to a built-in function that
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} is equivalent to
`vect_assign`

*expr*_{1} *expr*_{2} *expr*_{3}. In the initial environment,
the identifier `vect_assign`

resolves to a built-in function that
modifies in-place 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
built-in function returns `()`

. Hence, the whole expression *expr*_{1} `.(`

*expr*_{2} `)`

`<-`

*expr*_{3} evaluates to the unit value `()`

.

This behavior of the two constructs *expr*_{1} `.(`

*expr*_{2} `)`

and
*expr*_{1} `.(`

*expr*_{2} `)`

`<-`

*expr*_{3} may change if the meaning
of the identifiers `vect_item`

and `vect_assign`

is changed,
either by redefinition or by modification of the list of opened
modules. See the discussion below on operators.

The operators written `infix-op`

in the grammar above can appear
in infix position (between two expressions). The operators written
`prefix-op`

in the grammar above can appear in prefix position (in
front of an expression).

The expression *prefix-op* *expr* is interpreted as the application
*ident* *expr*, where *ident* is the identifier associated to the
operator *prefix-op* in the table below. Similarly, the expression
*expr*_{1} *infix-op* *expr*_{2} is interpreted as the application
*ident* *expr*_{1} *expr*_{2}, where *ident* is the identifier associated to the
operator *infix-op* in the table below. The identifiers written
*ident* above are then evaluated following the rules in
section 3.8. In the initial environment, they evaluate to
built-in functions whose behavior is described in the table. The
behavior of the constructions *prefix-op* *expr* and *expr*_{1} *infix-op* *expr*_{2} may change if the meaning of the identifiers associated to
*prefix-op* or *infix-op* is changed, either by redefinition of the
identifiers, or by modification of the list of opened modules, through
the `#open`

and `#close`

directives.

Operator | Associated ident | Behavior in the default environment |
---|---|---|

+ | prefix + | Integer addition. |

- (infix) | prefix - | Integer subtraction. |

- (prefix) | minus | Integer negation. |

* | prefix * | Integer multiplication. |

/ | prefix / | Integer division.
Raise Division_by_zero if second argument is zero. The result is
unspecified if either argument is negative. |

mod | prefix mod | Integer modulus. Raise
Division_by_zero if second argument is zero. The result is
unspecified if either argument is negative. |

+. | prefix +. | Floating-point addition. |

-. (infix) | prefix -. | Floating-point subtraction. |

-. (prefix) | minus_float | Floating-point negation. |

*. | prefix *. | Floating-point multiplication. |

/. | prefix /. | Floating-point division.
Raise Division_by_zero if second argument is zero. |

** | prefix ** | Floating-point exponentiation. |

@ | prefix @ | List concatenation. |

^ | prefix ^ | String concatenation. |

! | prefix ! | Dereferencing (return the current contents of a reference). |

:= | prefix := | Reference assignment (update the reference given as first argument with the value of the second argument). |

= | prefix = | Structural equality test. |

<> | prefix <> | Structural inequality test. |

== | prefix == | Physical equality test. |

!= | prefix != | Physical inequality test. |

< | prefix < | Test ``less than'' on integers. |

<= | prefix <= | Test ``less than or equal '' on integers. |

> | prefix > | Test ``greater than'' on integers. |

>= | prefix >= | Test ``greater than or equal'' on integers. |

<. | prefix <. | Test ``less than'' on floating-point numbers. |

<=. | prefix <=. | Test ``less than or equal '' on floating-point numbers. |

>. | prefix >. | Test ``greater than'' on floating-point numbers. |

>=. | prefix >=. | Test ``greater than or equal'' on floating-point numbers. |

The behavior of the `+`, `-`, `*`, `/`, `mod`, `+.`, `-.`, `*.` or
`/.` operators is unspecified if the result falls outside of the range
of representable integers or floating-point numbers, respectively. See
chapter 14 for a more precise description of the behavior
of the operators above.