## Expressions

    expr:
          ident
       |  variable
       |  constant
       |  ( expr )
       |  begin expr end
       |  ( expr : typexpr )
       |  expr , expr {, expr}
       |  ncconstr expr
       |  expr :: expr
       |  [ expr {; expr} ]
       |  [| expr {; expr} |]
       |  { label = expr {; label = expr} }
       |  expr expr
       |  prefix-op expr
       |  expr infix-op expr
       |  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 expr

    simple-matching:
          pattern -> expr {| pattern -> expr}

    multiple-matching:
          pattern-list -> expr {| pattern-list -> expr}

    pattern-list:
          pattern {pattern}

    let-binding:
          pattern = expr
       |  variable pattern-list = expr

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

### Simple expressions

#### Constants

Expressions consisting in a constant evaluate to this constant.

#### Variables

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.

#### Parenthesized expressions

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 `:` type `)`. This constraint forces the type of expr to be compatible with type.

#### Function abstraction

The most general form of function abstraction is:

    fun pattern11 ... pattern1M -> expr1
      | ...
      | patternN1 ... patternNM -> exprN

This expression evaluates to a functional value with m curried arguments. When this function is applied to m values v1 ... vm, the values are matched against each pattern row patterni1...patternim for i from 1 to n. If one of these matchings succeeds, that is if the value vj matches the pattern patternij for all j = 1, ..., m, then the expression expri associated to the selected pattern row is evaluated, and its value becomes the value of the function application. The evaluation of expri takes place in an environment enriched by the bindings performed during the matching.

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

    function pattern1 -> expr1
           | ...
           | patternN -> exprN

The 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 forms cconstr pattern (two patterns in a row) and ncconstr pattern (one pattern) cannot be distinguished syntactically. Function definitions introduced by `fun` resolve the ambiguity to the former form; function definitions introduced by `function` resolve it to the latter form (the former form makes no sense in this case).

#### Function application

Function application is denoted by juxtaposition of expressions. The expression expr1 expr2...exprn evaluates the expressions expr1 to exprn. The expression expr1 must evaluate to a functional value, which is then applied to the values of expr2,...,exprn. The order in which the expressions expr1,...,exprn are evaluated is not specified.

#### Local definitions

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

> `let` pattern1 `=` expr1 `and`...`and` patternn `=` exprn `in` expr

evaluates expr1...exprn in some unspecified order, then matches their values against the patterns pattern1...patternn. 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

> ident `=` `fun` pattern1...patternm `->` expr

in a `let` expression, one may instead write

> ident pattern1...patternm `=` expr

Both forms bind ident to the curried function with m arguments and only one case,

> pattern1...patternm `->` expr.

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

> `let` `rec` pattern1 `=` expr1 `and`...`and` patternn `=` exprn `in` expr

The only difference with the `let` construct described above is that the bindings of variables to values performed by the pattern-matching are considered already performed when the expressions expr1 to exprn are evaluated. That is, the expressions expr1 to exprn can reference identifiers that are bound by one of the patterns pattern1,...,patternn, 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 expr1 to exprn are function definitions (`fun`... or `function`...), and the patterns pattern1...patternn consist in a single variable, as in:

> `let` `rec` ident1 `=` `fun`...`and`...`and` identn `=` `fun`...`in` expr

This defines ident1...identn as mutually recursive functions local to expr. The behavior of other forms of `let rec` definitions is implementation-dependent.

### Control constructs

#### Sequence

The expression expr1 `;` expr2 evaluates expr1 first, then expr2, and returns the value of expr2.

#### Conditional

The expression `if` expr1 `then` expr2 `else` expr3 evaluates to the value of expr2 if expr1 evaluates to the boolean `true`, and to the value of expr3 if expr1 evaluates to the boolean `false`.

The `else` expr3 part can be omitted, in which case it defaults to `else` `()`.

#### Case expression

The expression

    match expr with
          pattern1 -> expr1
        | ...
        | patternN -> exprN

matches the value of expr against the patterns pattern1 to patternn. If the matching against patterni succeeds, the associated expression expri is evaluated, and its value becomes the value of the whole `match` expression. The evaluation of expri 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.

#### Boolean operators

The expression expr1 `&` expr2 evaluates to `true` if both expr1 and expr2 evaluate to `true`; otherwise, it evaluates to `false`. The first component, expr1, is evaluated first. The second component, expr2, is not evaluated if the first component evaluates to `false`. Hence, the expression expr1 `&` expr2 behaves exactly as

> `if` expr1 `then` expr2 `else` `false`.

The expression expr1 `or` expr2 evaluates to `true` if one of expr1 and expr2 evaluates to `true`; otherwise, it evaluates to `false`. The first component, expr1, is evaluated first. The second component, expr2, is not evaluated if the first component evaluates to `true`. Hence, the expression expr1 `or` expr2 behaves exactly as

> `if` expr1 `then` `true` `else` expr2.

#### Loops

The expression `while` expr1 `do` expr2 `done` repeatedly evaluates expr2 while expr1 evaluates to `true`. The loop condition expr1 is evaluated and tested at the beginning of each iteration. The whole `while`...`done` expression evaluates to the unit value `()`.

The expression `for` ident `=` expr1 `to` expr2 `do` expr3 `done` first evaluates the expressions expr1 and expr2 (the boundaries) into integer values n and p. Then, the loop body expr3 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 `=` expr1 `downto` expr2 `do` expr3 `done` first evaluates the expressions expr1 and expr2 (the boundaries) into integer values n and p. Then, the loop body expr3 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 `()`.

#### Exception handling

The expression

    try  expr
    with pattern1 -> expr1
        | ...
        | patternN -> exprN

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 pattern1 to patternn. If the matching against patterni succeeds, the associated expression expri is evaluated, and its value becomes the value of the whole `try` expression. The evaluation of expri 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.

### Operations on data structures

#### Products

The expression expr1 `,`...`,` exprn evaluates to the n-tuple of the values of expressions expr1 to exprn. The evaluation order for the subexpressions is not specified.

#### Variants

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 expr1 `::` expr2 stands for the constructor `prefix` `::` applied to the argument `(` expr1 `,` expr2 `)`, and therefore evaluates to the list whose head is the value of expr1 and whose tail is the value of expr2. The expression `[` expr1 `;`...`;` exprn `]` is equivalent to expr1 `::`...`::` exprn `::` `[]`, and therefore evaluates to the list whose elements are the values of expr1 to exprn.

#### Records

The expression `{` label1 `=` expr1 `;`...`;` labeln `=` exprn `}` evaluates to the record value `{` label1 `=` v1 `;`...`;` labeln `=` vn `}`, where vi is the value of expri for i = 1, ..., n. The labels label1 to labeln 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 expr1 to exprn are evaluated is not specified.

The expression expr1 `.` label evaluates expr1 to a record value, and returns the value associated to label in this record value.

The expression expr1 `.` label `<-` expr2 evaluates expr1 to a record value, which is then modified in-place by replacing the value associated to label in this record by the value of expr2. This operation is permitted only if label has been declared `mutable` in the definition of the record type. The whole expression expr1 `.` label `<-` expr2 evaluates to the unit value `()`.

#### Arrays

The expression `[|` expr1 `;`...`;` exprn `|]` evaluates to a n-element array, whose elements are initialized with the values of expr1 to exprn respectively. The order in which these expressions are evaluated is unspecified.

The expression expr1 `.(` expr2 `)` is equivalent to the application `vect_item` expr1 expr2. In the initial environment, the identifier `vect_item` resolves to a built-in function that returns the value of element number expr2 in the array denoted by expr1. 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 expr1 `.(` expr2 `)` `<-` expr3 is equivalent to `vect_assign` expr1 expr2 expr3. In the initial environment, the identifier `vect_assign` resolves to a built-in function that modifies in-place the array denoted by expr1, replacing element number expr2 by the value of expr3. The exception `Invalid_argument` is raised if the access is out of bounds. The built-in function returns `()`. Hence, the whole expression expr1 `.(` expr2 `)` `<-` expr3 evaluates to the unit value `()`.

This behavior of the two constructs expr1 `.(` expr2 `)` and expr1 `.(` expr2 `)` `<-` expr3 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.

### 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 expr1 infix-op expr2 is interpreted as the application ident expr1 expr2, 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 expr1 infix-op expr2 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.