Topazdocs
Политика языка

Шаблоны и управление потоком

Каноническая грамматика, семантика, ограничения и отложенные границы: Шаблоны и управление потоком.

Управление ориентировано на выражения, а pattern точно задаёт, как единожды вычисленное значение проверяется, сужается, разбирается, связывается и учитывается в coverage.

Политика

if и match дают значение при согласованных ветвях. Каждая ветвь match начинается с case, catch-all — _. Есть literal, range, binding, type, constructor, array с rest .., structural record, nominal record и упорядоченный or-pattern. if let вычисляет scrutinee один раз и создаёт immutable bindings только в success-body; while let повторяет тест до первого несовпадения.

Определённое поведение

Ветка с guard не даёт exhaustiveness coverage. Закрытый enum проверяется по вариантам и irrefutable payload. List-rest получает Array<T>. Nominal-record pattern сначала проверяет declaration identity, затем поля слева направо. Or-pattern испытывает альтернативы слева направо со scratch bindings; binding-альтернативы должны иметь одинаковые имена и связанный overlap type. Выражение for собирает хвосты body по порядку, а instruction-for и while значения не дают.

Ограничения и явный отказ

Запрещены ...rest, qualified enum cases, пустой nominal-record pattern, parenthesized pattern, while let ... else, guard в голове if let и утечка bindings. Несовпадение refutable pattern в comprehension — fault, не фильтр. Bare break/continue требуют локальную цель; только контекстный loop объявляет labels и объединяет break values. Top-level return и общие statement arms у match статически ошибочны.

Отложенная граница

Goto-like labels, labels у while/for, переход через функцию, публичный Never, усиленные termination claims, расширенные pattern heads и fault-catching control отложены. Если scrutinee недостаточно конечен для статической проверки, канонический пример использует явный catch-all.

Пример

TOPAZ
function describe(values: Array<int>) -> string {
    match values {
        case [] => "empty"
        case [only] => "one: {only}"
        case [head, ..tail] => "head: {head}, rest: {tail.length}"
    }
}

let label = describe([1, 2, 3])

Связанные правила