# Глава 6. Язык Objective Caml

## 6.1 Введение

Эта глава является справочником по языку Objective Caml. Она перечисляет языковые конструкции и дает их точный синтаксис и неформальную семантику. Она никоим образом не может считаться учебником, и в ней нет ни одного примера кода. Ожидается, что читатель хорошо знает Caml.

Нет здесь и математической точности. Слова употребляются в их обычном значении. Соотвественно, правила оформления также не соблюдаются в силу отсутствия математеского аппарата, необходимого для их формулировки. Тем не менее, они, разумеется, являются частью полного формального определения языка.

### Нотация

Синтаксис языка приведен в нотации, напоминающей BNF. Терминальные символы обозначаются таким образом. Нетерминальные символы оформлены так. В квадратных скобках ([...]) перечислены необязательные элементы. Фигурные скобки ({...}) обозначают ноль и более повторяющихся компонентов. Если фигурные скобки сопровождаются знаком плюса ({...}+), то это означает, что компонент повторяется один и более раз. Круглые скобки ((...)) означают группировку.

## 6.2 Лексические соглашения

### Пробельные символы

Пробельными символами считаются: пробел, символ новой строки, горизонтальная табуляция, перевод строки, возврат каретки, подача страницы. Они игнорируются, но используются для разделения идентификаторов, литералов и ключевых слов, которые в противном случае считались бы одним идентификатором, литералом или ключевым словом.

### Комментарии

Комментарии начинаются начинаются знаками (* без пробела между ними и заканчиваются знаками *) без пробела между ними. Они считаются пробельными символами и не могут находится внутри строки или символьного литерала. Вложенные комментарии обрабатываются правильно.

### Идентификаторы

ident | ::= | ( letter | ... ) { letter | 0...9 | _ | ' }

letter | ::= | A...Z | a...z

Идентификаторы состоят из последовательности букв, цифр, _ (символов подчеркивания), ' (одинарных кавычек), начинающейся с буквы или символа подчеркивания. Буквы включают по крайней мере пятьдесят два символа из набора ASCII в верхнем и нижнем регистрах. Текущая реализация (за исключением платформы MacOS) допускает также симоволы с акцентами из ISO 9959-1 (или ISO Latin 1). Значимы все символы в идентификаторе, и в текущей реализации его длина не ограничивается.

### Целочисленные литералы

integer-literal | ::= | [ - ] { 0..9 } + | [ - ] ( 0x | 0X ) { 0...9 | A...F | a..f } + | [ - ] ( 0o | 0O ) { 0...7 } + | [ - ] ( 0b | 0B ) { 0...1 } +

Целочисленный литерал - это последовательность из одной или нескольких цифр, которой может предшествовать знак минус. По умолчанию целочисленные литералы считаются десятичными (основание 10). Основание изменяется следующими префиксами:

Префикс | Основание
--- | ---
`0x, 0X` | шестнадцатиричное (основание 16)
`0o, 0O` | восьмеричное (основание 8)
`0b, 0B` | двоичное (основание 2)

(Первое `0` - цифра ноль, второе `o` для двоичных чисел - буква "O"). Интерпретация целочисленных литералов, не попадающих в приемлемый диапазон значений для целого числа, не определена.

### Литералы для чисел с плавающей точкой

float-literal | ::= | [ - ] { 0...9 } + [ . { 0...9 } ] [ ( e | E ) [ + | - ] { 0...9 } + ]

Литералы для чисел с плавающей точкой состоят из трех частей - целочисленной, десятичной и экспоненты. Целочисленная часть - это последовательность из одной или нескольких цифр с необязательным знаком плюс или минус. Десятичная - точка, за которой следуют ноль или более цифр. Экспонента - буква `e` или `E`, необязательный знак плюс или минус и одна или более цифр. Десятичная часть или экспонента могут быть опущены, однако лучше, чтобы присутствовала хоть одна из них, чтобы число отличалось от целочисленных литералов. Интерпретация литералов для чисел с плавающей точкой, не попадающих в приемлемый диапазон, не определена.

### Символьные литералы

char-literal | ::= | ' regular-char ' | ' escape-sequence '

escape-sequence | ::= | \ ( \ | " | ' | n | t | b | r ) | \ ( 0...9 ) ( 0...9 ) ( 0...9 )

Символьные литералы ограничиваются одинарными кавычками (`'`). Две одинарные кавычки могут ограничивать либо один символ, отличный от ' и \, либо одну из управляющих последовательностей ниже:

Последовательность | Обозначаемый символ
--- | ---
`\\` | Обратная косая черта (\)
`\"` | Двойная кавычка (")
`\'` | Одинарная кавычка (')
`\n` | Перевод строки (LF)
`\r` | Возврат каретки (CR)
`\t` | Горизонтальная табуляция (TAB)
`\b` | Забой (BS)
`\ddd` | Символ с десятичным кодом ASCII `ddd`

### Строковые литералы

string-literal | ::= | " { string-character } "

string-character | ::= | regular-char | escape-sequence

Строковые литералы ограничиваются двойными кавычками (`"`). Двойные кавычки могут ограничивать либо один символ, отличный от ' и \, либо одну из управляющих последовательностей из таблицы выше.

Чтобы длинные строковые литералы можно было разбивать на несколько строк, последовательность \newline blanks (обратная косая черта внутри строки, за которой следует произвольное число пробельных символов в начале следующей строки) игнорируется.

В текущей реализации длина строковых литералов практически не ограничена

### Именованные метки

Во избежание двусмысленностей именованные метки нельзя просто определить синтаксически как последовательность трех токенов ~, ident и `:`. Они требуют определения на лексическом уровне.

label | ::= | ~ ( a...z ) { letter | 0...9 | _ | ' } + :

oplabel | ::= | ? ( a...z ) { letter | 0...9 | _ | ' } + :

Именованные метки бывают двух видов: label для обычных аргументов и optlabel для необязательных. Они отличаются только первым символом - `~` или `?`.

### Префиксные и инфиксные символы

infix-symbol | ::= | ( = | < | > | @ | ^ | | | & | + | - | * | / | $ | % ) { operator-char }

prefix-symbol | ::= | ( ~ | ! | ? ) { operator-char }

operator-char | ::= | ! | : | . | ~ | = | < | > | @ | ^ | | | & | + | - | * | / | $ | %

Последовательности "символов операторов" типа `<=>` или `!!` читаются как один токен из классов infix-char или prefix-char. Такие символы разбраются как префиксные или инфиксные операторы внутри выражения или же ведут себя как идентификаторы.

### Ключевые слова

Следующие идентификаторы считаются ключевыми словами и не могут использоваться в другом качестве:

    and         as          assert      asr         begin       class
    closed      constraint  do          done        downto      else
    end         exception   external    false       for         fun
    function    functor     if          in          include     inherit
    land        lazy        let         lor         lsl         lsr
    lxor        match       method      mod         module      mutable
    new         of          open        or          parser      private
    rec         sig         struct      then        to          true
    try         type        val         virtual     when        while
    with

Следующие последовательности символов также считаются ключевыми словами:

    #     &     '     (     )     *     ,     ->    ?
    ??    .     ..    .(    .[    :     ::    :=    ;
    ;;    <-    =     [     [|    [<    {<    ]     |]
    >]    >}    _     `     {     |     }     ~

### Неоднозначности

Лексические неоднозначности решаются по правилу "длиннейшего совпадения": если последовательность символов может быть разбита на два токена несколькими способами, используется тот способ, который дает наиболее длинный первый токен.

### Директивы номера строки

linenum-directive | ::= | # { 0...9 } + | # { 0...9 } + " string-character "

Препроцессоры, генерирующие исходный код на Caml, могут помещать в свой вывод директивы номера строки, и тогда компилятор сможет добавлять к сообщениям об ошибках имена строк и имена файлов до предварительной обработки, а не после нее. Директива номера строки состит из `#` (знак диеза), за которым следует положительное целое число (номер строки) и, возможно, символьная строка (имя файла). Во время лексического анализа директивы номера строки считаются пробельными символами.

## 6.3 Типы данных

В этом разделе описываются типы данных, обрабатываемых в Objective Caml.

### 6 . 3.1 Базовые типы

#### Целые числа

Целочисленными значениями считаются целые числа от -230 до 230 - 1, то есть от -1073741824 до 1073741823. Реализация может поддерживать больший диапазон значений: в настоящее время на 64-разрядных платформах поддерживаются целые от -262 до 262 - 1

#### Числа с плавающей точкой

Значениями с плавающей точкой считаются числа в одноименном представлении. Текущая реализация использует числа с плавающей точкой с двойной точностью согласно стандарту ISO 754 c мантиссой 53 бита и экспонентой от -1024 до 1024.

#### Символы

Символы представлены как 8-битные целые числа от 0 до 255. Коды символов от 0 до 127 интерпретируются по стандарту ASCII. Текущая реализация интерпретирует коды символов от 127 до 255 по стандарту ISO 8859-1.

#### Символьные строки

Символьная строка - это конечная последовательность символов. Текущая реализация поддерживает строки, содержащие до 224 - 6 (то есть, 16777210) символов.

### 6 . 3.2 Кортежи

Кортежи значений записываются как `(v1, ..., vn)`, что соотвествует n-кортежу из значений от v1 до vn. Текущая реализация поддерживает кортежи из максимум 222 - 1 (то есть 4194303) элементов.

### 6 . 3.3 Записи

Записи являются кортежами именованных значений. Запись `{field1=v1; ... ; fieldn=vn}` связывает значение vi с полем записи fieldi для i=1 ... n. Текущая реализация поддерживает записи из максимум 222 - 1 (то есть 4194303) элементов.

### 6 . 3.4 Массивы

Массивы - это конечные, переменного размера последовательности значений одного типа. Текущая реализация поддерживает массивы из максимум 222 - 1 (то есть 4194303) элементов.

### 6 . 3.5 Вариантные значения

Вариантные значения являются либо константными конструкторами, либо парой из неконстантного конструктора и значения. Первый случай записывается как `cconstr`, второй - как `ncconstr(v)`, где `v` - аргумент для неконстантного конструктора `ncconstr`.

Следующие константы считаются встроенными константными конструкторами:

Константа | Конструктор
--- | ---
`false` | булево значение false
`true` | булево значение true
`()` | значение "unit"
`[]` | пустой список

Текущая реализация ограничивает число конструкторов для данного вариантного типа числом 249.

### 6 . 3.6 Полиморфные варианты

Полиморфные варианты - это альтернативная форма вариантного типа. Они не принадлежат явно к предопределенному вариантному типу и подчиняются особым правилам типизации. Они могут записываться либо как константы - ``tag-name`, либо, в случае не константы, как ``tag-name(n)`.

### 6 . 3.7 Функции

Функции являются отображением значений на значения.

### 6 . 3.8 Объекты

Объекты включают скрытое внутреннее состояние, выражаемое как переменные экземпляра, и набор методов, предназначенных для доступа к этом переменным и их изменения. Структура объекта описывается в порождающем его классе.

## 6.4 Имена

Идентификаторы используются для именования некторых классов языковых объектов и возмоджности обращения к этим объектам по имени. Это:

- имена значений (синтаксический класс value-name)

- конструкторы значений (для константных - класс cconstr-name, для неконстантных - ncconstr-name)

- метки (label-name)

- теги вариантов (tag-name)

- конструкторы типов (typeconstr-name)

- поля записей (field-name)

- имена классов (class-name)

- имена методов (method-name)

- имена переменных экземпляра (inst-var-name)

- имена модулей (module-name)

- имена типов модулей (modtype-name)

Эти девять пространств имен как по контексту, так и по регистру имени: первая буква идентификатора может быть строчной (ниже lowercace-ident) или заглавной (ниже capitalized-ident). Знак подчеркивания в данном случае считается строчной буквой.

### Именование объектов

value-name | ::= | lowercase-ident | ( operator-name )

operator-name | ::= | prefix-symbol | infix-symbol | * | = | or | & | :=

cconstr-name | ::= | capitalized-ident | false | true | [ ] | ( )

ncconstr-name | ::= | capitalized-ident | ::

label-name | ::= | lowercase-ident

tag-name | ::= | capitalized-ident

typeconstr-name | ::= | lowercase-ident

field-name | ::= | lowercase-ident

module-name | ::= | capitalized-ident

modtype-name | ::= | ident

class-name | ::= | lowercase-ident

inst-var-name | ::= | lowercase-ident

method-name | ::= | lowercase-ident

Как видно, префиксные и инфиксные символы, а также некторые ключевые слова можно использовать как имена значений, если заключить их в кавычки. Такие ключевые слова как 'false' и '::' являются также именами конструкторов. Правила относительно регистра имен подытожены в следующей таблице:

Пространство имен | Первая буква
--- | ---
Значения | строчная
Конструкторы | прописная
Метки | прописная
Теги вариантов | прописная
Конструкторы типа | строчная
Поля записей | строчная
Классы | строчная
Методы | строчная
Модули | прописная
Типы модулей | любая

Относительно тегов вариантов: текущая реализация принимает их в дюбом регистре, однако ради переносимости и совместимости с будущими версиями OCaml рекомендуется избегать использовать в качесте первого симовла их имен строчные буквы.

### Ссылки на именованные объекты

value-path | ::= | value-name | module-path . lowercase-ident

cconstr | ::= | cconstr-name | module-path . capitalized-ident

ncconstr | ::= | ncconstr-name | module-path . capitalized-ident

typecontstr | ::= | typeconstr-name | extended-module-path . lowercase-ident

field | ::= | field-name | module-path . lowercase-ident

module-path | ::= | module-name | module-path . capitalized-ident

extended-module-path | ::= | module-name | extended-module-path . capitalized-ident | extended-module-path ( extended-module-path )

modtype-path | ::= | modtype-name | extended-module-path . ident

class-path | ::= | class-name | module-path . lowercase-ident

На именованный объект можно ссылаться либо по имени (учитывая обычные статичные правила области видимости для имен), либо через путь доступа вида prefix . name, где prefix означает модуль, а name - имя объекта, определенного в этом модуле. Первый компонент пути prefix записывается либо как простое имя модуля, либо путь доступа вида name1 . name2... в случаях, когда определяющий модуль сам вложен в другие модули. При ссылке на конструкторы типа или типы модуля prefix также может содержать простые вызовы функтора (как в синтаксическом классе extended-module-path), если определяющий модуль сам является результатом вызова функтора.

Имена меток, тегов, методов и переменных экземпляров такого уточнения не требуют: метки, теги и методы глобальны, а переменные экземпляра локальны в пределах класса.

## 6.5 Выражения типа

typexpr | ::= | ' ident | _ | ( typexpr ) | [ [ ? ] ident : ] typexpr -> typexpr | typexpr { * typexpr } +
| typeconstr
| typexpr typeconstr
| ( typexpr { , typexpr } ) typeconstr
| typexpr as ' ident
| [ variant-type ]
| < [ .. ] >
| < method-type { ; method-type } [ ; .. ] >
| # class-path
| typexpr # class-path
| ( typexpr { , typexpr } ) # class-path

poly-typexpr | ::= | typexpr | { ' ident } + . typexpr

method-type | ::= | method-name : poly-typexpr

В таблице ниже привены относительные приоритет и ассоциативность операторов и конструкций незакрытых типов. Операторы с высшим приоритетом помещены в таблицу первыми.

Оператор | Ассоциативность
--- | ---
Вызов конструктора типа | --
* | --
-> | правая
as | --

Выражения типа обозначают типы в определениях типов данных, а также в ограничениях типа в образцах и выражениях.

### Переменные типа

Выражение типа ' ident означает переменную типа с именем ident. Выражение _ означает анонимную переменную типа. В определениях типов данных переменные являются именами параметров этих типов. В ограничениях они соответствуют непредусмотренным типам, которые могут быть созданы любым типом, чтобы соответствовать ограничению. Область действия именованной переменной как правило ограничивается типом, в котором она определена, а за его пределами она может быть только обобщенной. Анонимые переменные такого ограничения не имеют.

### Типы в скобках

Выражение ( typexpr ) означает то же самое, что и typexpr.

### Типы функций

Выражение типа typexpr 1 -> typexpr 2 означает тип функций,отображающий аргументы типа typexpr 1 на результаты типа typexpr 2.

label typexpr 1 -> typexpr 2 означает тот же тип функции, однако аргумент помечается меткой label.

? label typexpr 1 -> typexpr 2 означает тип функций,отображающий необязательные аргументы с меткой типа typexpr 1 на результаты типа typexpr 2. Иными словами, физический тип функции будет typexpr 1 option -> typexpr 2.

### Типы кортежей

Выражение типа typexpr1 *...* typexprnозначает тип кортежа, элементы которого принадлежат к типам typexpr1, ... typexprn, соответственно.

### Типы конструкторов

Конструктор типа без параметров, как в случае typeconstr, является выражением типа.

Выражение типа typexpr typeconstr, где typeconstr - конструктор типа с одним параметром, означает применение унарного конструктора типа typeconstr к типу typexpr.

Выражение типа (typexpr1,...typexprn) typeconstr, где typeconstr - конструктор типа с n параметров, означает применение n-нарного коструктора типа typeconstr к типам с typexpr1 по typexprn.

### Вариантные типы

variant-type | ::= | [ | ] tag-spec { | tag-spec } | > [ tag-spec ] { | tag-spec } | < [ | ] tag-spec-full { | tag-spec-full } [ > { ` tag-name } + ]

tag-spec | ::= | ` tag-name [ of typexpr ] | typexpr

tag-spec-full | ::= | ` tag-name [ of typexpr ] { & typexpr } | typexpr

Вариантные типа описывают возможные значения полиморфного варианта.

Первый случай является точным вариантным типом: все возможные теги известны, как и связанные с ними типа, и все они могут присутствовать в значении. Структура полностью известна.

Второй случай представляет открытый вариантный тиа, описывающий полиморыное вариантное значение: здесь дается список тегов для возможного значения, а также связанные с ними типы. Такой тип все еще совместим с вариантным типом, содержащим несколько тегов. Особый случай представляет собой неизвестный тип, вовсе не определяющий тегов, но совместимый с любым вариантным типом.

В третьем случае описывается закрытый вариантный тип. Он предоставляет информацию о всех возможных тегах и связанных с ними типах, а также о том, какие теги могут появиться в значениях. Точный вариантный тип является на самом деле сокрашением закрытого вариантного типа, в котором все возможные теги также уже потенциально присутствуют.

Во всех трех случаях теги либо описываются непосредственно в форме ``tag-name [...]`, либо опосредованно, через выражение типа - тогда оно должно разворачиваться в точный вариантный тип, причем спецификации тегов должны помещаться на свое место.

Полная спецификация вариантных тегов используется только для неточных закрытых типов. Их можно считать конъюнктивным типом для аргумента, перечисляющим все типы в спецификации.

Такое конъюнктивное ограничение может оказаться недостаточным. В подобных ситуациях соответствующий тег может не использоваться в значении такого типа, что не означает ошибки типа: можно ведь использовать и другие доступные теги.

### Объектные типы

Объектный тип < method-type { ; method-type } ; является записью типов метода.

Каждый метод может иметь явныей полиморфный тип: { ' ident }+ . typexpr. Явные полиморфные переменные имеют локальную область видимости, кроме того, явный полиморфный тип может быть унифицирован только со своим эквивалентом, полиморфные переменные которого стоят на тех же местах.

Тип < method-type { ; method-type } ; .. > является типом объекта с методами и связанными с ними типами, описанными в method-type1, ..., method-typen и вероятно еще какими-то методами, представленными многоточие, которое на самом деле считается особым типом перменной (также называемой row variable), заменяющей любое количество дополнительных типов метода.

### Типы #

Тип # class-path - особый случай сокращения, унифицируемого с типом любого объекта, принандлежащего к субклассу класса class-path. Он обрабатывается особым образом, так как обычно скрывает тип переменной в многоточии, представляющем методы, которые могут быть добавлены в субкласс. В частности, этот тип уничтожается при инстанциировании многоточия. Каждое выражение # class-path определяет новую переменную, поэтому тип # class-path -> # class-path, как правило, отличается от типа (# class-path as 'ident)-> 'ident.

Использование таких типов для сокращения вариантов не рекомендуется. Если `t` - точный вариантный тип, то `#t` транслируется в `[< t]`, а #t[> `tag1 ... `tagk] - в [< t > `tag1 ... `tagk].

### Типы вариантов и записей

Выражений типа описывающих определенные типы вариантов и записей нет, так как они всегда имеют имя, то есть определяются до использования и ссылки на них. Определения типов описаны в разделе 6.8.1.

## 6.6 Константы

constant | ::= | integer-literal | float-literal | char-literal | string-literal | `tag-name

Синтаксический класс констант включает литералы четырех базовых типов (целые, числа с плавающей точкой, символы, симовольные строки) и константные конструкторы как нормальных, так и полиморфных вариантов.

## 6.7 Образцы

pattern | ::= | value-name | _ | constant | pattern as value-name | ( pattern )
| ( pattern : typexpr )
| pattern | pattern
| ncconstr pattern
| ` tag-name pattern
| # typeconstr-name
| pattern { , pattern }
| { field = pattern { ; field = pattern } }
| [ pattern { ; pattern } ]
| pattern :: pattern
| [| pattern { ; pattern } |]

В таблице ниже показан относительный приоритет и ассоциативность незакрытых конструкций образцов. Элементы с высшим приоритетом помещены в таблицу первыми.

Оператор | Ассоциативность
--- | ---
Вызов конструктора | --
:: | правая
, | --
| | левая
as | --

Образцы - это шаблоны, позволяющие выбирать структуры данных определенной формы и связывать идентификаторы с компонентами структуры данных. Операция выбора называется сопоставлением по образцу; ее результат - либо "это значение не подходит для этого образца", либо "значение подходит для образца, что дает в резулльтате связывание имен со значениями".

### Образцы переменных

Образец, включающий только имя значения совпадает с любым значением и связывает последнее с именем. Образец _ также совпадает с любым значением, но не дает связывания.

Образцы линейны: переменная может встречаться в конкретном образцк несколько раз. В частности, использование только образца не позволяет проверить на равенство две части структуры данных (впрочем, для этой цели может быть использована конструкция when).

### Образцы констант

Образец, включающий лишь константу, совпадает со значением, равным этой константе.

### Образцы псевдонимов

Образец pattern1 as value-name совпадает с теми же значениями, что и pattern1. Если сопоставление с pattern1 успешно, то помимо связывания в результате этой операции имя name связывается с совпавшим значением.

### Образцы в скобках

Образец ( pattern1 ) совпадает с теми же значениями, что и pattern1. Кроме того, в такой форме может присутствовать ограничение типа: ( pattern1 : typexpr ). Оно требует, чтобы тип pattern1 был совместим с type.

### Образцы "или"

Образец pattern1 | pattern2 представляет собой логическое "или" двух образцов. Значение, совпадающее с ним, должно совпадать либо с pattern1, либо с pattern2. Образцы pattern1 и pattern2 должны связывать точно одни и те же идентификаторы с переменными, имеющими такой же тип. Связывание осущесьтвляется либо при успешном сопоставлении с pattern1, либо с pattern2. Если успешны оба сопоставления, конкретный выбор связывания неопределен.

### Образцы вариантов

Образец ncconstr pattern1 совпадает со всеми вариантами, конструкторы которых равны ncconstr, а аргументы совпадают с pattern1.

Образец pattern1 :: pattern2 совпадает с непустым списком, первый элемент которого совпадает с pattern1, а последний - с pattern2. Этот образец работает так же, как (::) ( pattern1 , pattern2 ).

Образец [ pattern1 ; ... ; patternn ] совпадает со списоком из n элементов, совпадающих с образцами pattern1 ... patternn, соответственно. Он работает так же, как и pattern1 :: ... :: patternn [].

### Образцы полиморфных вариантов

Образец `tag-name pattern1 совпадает с любым полиморфным вариантом, тег которого равен tag-name, а аргумент совпадает с pattern1.

### Образцы сокращений вариантов

Если определен тип [('a, 'b, ...)] typeconstr =[ `tag1 t1 | ... `tagn tn, то образец #typeconstr является сокращеним для образца-или (`tag1(_:t1 )| ... | (`tagn(_:tn )) и совпадает с любым значением типа #typeconstr.

### Образцы кортежей

Образец pattern1 , ... , patternn совпадает с n-элементным кортежем, компоненты которого совпадают с образцами от pattern1 до patternn. Иначе говоря, образец совпадает со значениями кортежа (v1, ..., vn) так, что patterni совпадаетс с vi для i = 1, ... , n.

### Образцы записей

Образец { field1 = pattern1 ; ... ; fieldn = patternn } совпадает с записью, в которой определены по крайней мере поля от field1 до fieldn так, чтобы значение, связанное с полем fieldi совпадало с образцом patterni для i = 1, ..., n. Запись может определять больше полей, но значения, связанные с ними не учитываются при сопоставлении.

### Образцы массивов

Образец [| pattern1 ; ... ; patternn |] совпадает с массивом длины n так, что элемент с индексом i совпадает с образцом patterni для i = 1, ..., n.

## 6.8 Выражения

expr | ::= | value-path | constant | ( expr ) | begin expr end | ( expr : typexpr )
| expr , expr { , expr }
| ncconstr expr
| ` tag-name expr
| expr :: expr
| [ expr { ; expr } ]
| [| expr { ; expr } |]
| { field = expr { ; field = expr } }
| { expr with field = expr { ; field = expr } }
| expr { argument } +
| prefix-symbol expr
| expr infix-op expr
| expr . field
| expr . field <- expr
| expr .( expr )
| expr .( expr ) <- expr
| expr .[ expr ]
| expr .[ expr ] <- 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 pattern-matching
| function pattern-matching
| fun pattern-matching
| try expr with pattern-matching
| let [ rec ] let-binding { and let-binding } in expr
| new class-path
| expr # method-name
| ( expr :> typexpr )
| ( expr : typexpr :> typexpr )
| {< inst-var-name = expr { ; inst-var-name = expr } >}

argument | ::= | expr | ~ label-name | ~ label-name : pattern | ? label-name | ? ( label-name [ : typexpr ] [ = expr ] )
| ? label-name : pattern
| label-name : ( pattern [ : typexpr ] [ = expr ] )

infix-op | ::= | infix-symbol | * | = | or | &

В таблице ниже показан относительный приоритет и ассоциативность незакрытых конструкций. Элементы с высшим приоритетом помещены в таблицу первыми. Для инфиксных и префиксных символом значение "*" читается как "любой символ, начинающийся с *".

Конструкция или оператор | Ассоциативность
--- | ---
префиксный символ | --
. .( .[ | --
применение функции | левая
применение конструктора | --
- -. (префикс) | --
**... | правая
*... /... %... `mod` | левая
+... -... | левая
:: | правая
@... ^... | правая
сравнения (= == < и т.д), остальные инфиксные симвооы | левая
`not` | --
`&` `&&` | левая
`or ||` | левая
`,` | --
`<- :=` | правая
`if` | --
`;` | правая
`let match fun function try` | --

### Основные выражения

#### Константы

Выражения, включающие лишь константы, вычисляются в эти константы.

#### Путь к значению

Выражения, включающие путь к значению вычисляются в значение, связанное с этим путем в текущей среде. Путь может быть именем значения или путем доступа к значению, входящему в модуль.

#### Выражения в скобках

Выражения ( expr ) и begin expr end означают то же, что и expr. Обе формы семантически экивалентны, но в контрольных стуктурах считается хорошим стилем использовать begin ... end:

    if ... then begin ... ; ... end else begin ... ; ... end

а во всех остальных ситуациях, требующих группировки, использовать круглые скобки.

Также скобки позволяют включать в вырежение ограничение типа - ( expr : type ) - в этм случае тип выражения должен быть совместим с type.

Наконец, выражения в скобках могут содержать приведения: ( expr [ : type ] :> type) (см. раздел 6.8.5).

#### Применение функций