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

Null, Option, Result и ошибки

Каноническая грамматика, семантика, ограничения и отложенные границы: Null, Option, Result и ошибки.

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

Политика

Option<T> — канонический контейнер отсутствия; T | null предназначен для nullable data boundaries. ?? снимает ровно один слой Option/null и вычисляет fallback только при пустоте. ?. вычисляет receiver один раз, short-circuit аргументы, сохраняет модель Option/null и уплощает один optional-слой member. Instruction-only ??= присваивает только при пустоте и не оборачивает Some. Восстанавливаемая ошибка использует Result<T,E>, Ok, Err и постфиксный ?.

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

expr? снимает Ok или немедленно возвращает тот же Err из совместимой функции/лямбды. Fault не является значением: bounds failure, целочисленное деление на ноль, динамический нулевой step, overflow, отрицательная степень и runtime match miss прерывают вычисление. ?, ??, optional chaining и concurrent не ловят fault. Безопасные чтения коллекций возвращают Option.

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

?. недопустим для обычной non-null записи. Отклоняются ??= у nonoptional target, raw T в Option<T> ??=, ? вне совместимого Result-callable, случайный Err(Err(...)), синтаксис try, panic keyword и обычный public assert. Union, смешивающий Option и null, неканоничен до явного match.

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

Fault catching, exceptions, общий try, stack recovery, conversion отмены, автоматический retry и широкие assertion frameworks отложены. Host cleanup после fault возможен как runtime policy, но язык не обещает Result-преобразование или выполнение всех lexical defer.

Пример

TOPAZ
function parsePort(text: string) -> Result<int, string> {
    match toInt(text) {
        case Some(port) => Ok(port)
        case None => Err("port must be an integer")
    }
}

function start(text: string) -> Result<string, string> {
    let port = parsePort(text)?
    return Ok("listening on {port}")
}

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