Стандартная библиотека и среда

Поведение среды выполнения

Вывод, числовые результаты, безопасный поиск, ошибки, устойчивый порядок и намеренно не заданное поведение.

Даже после успешной проверки программа во время выполнения создаёт значения, вывод и возможные ошибки. Начнём с того, что видит пользователь: напечатанного текста, вычисленных значений, порядка коллекций и явной ошибки выполнения.

Наблюдаем обычные значения

Сохраните следующий код как runtime-behavior.tpz:

TOPAZ
let values = [10, 20]

print("int: {7 / 2} {-7 % 3}")
print("float: {1.5 + 1.5}")
print("safe: {values.get(9)}")

Запустите его командой topaz run runtime-behavior.tpz:

Вывод
int: 3 -1
float: 3.0
safe: None

print принимает только string. Перед вызовом интерполяция преобразует целое число, число с плавающей точкой и Option в отображаемый текст. В Prelude нет отдельной открытой функции println; используйте точную функцию print, показанную здесь.

int — знаковое 64-разрядное целое. Целочисленное деление усекает к нулю, а остаток получает знак делимого. Переполнение во время выполнения и деление на ноль вызывают ошибку, а не циклическое переполнение. float соответствует IEEE-754 binary64 и подчиняется правилам арифметики с плавающей точкой, а не десятичной арифметики.

values.get(9) возвращает None: отсутствие элемента является нормальным исходом безопасного поиска.

Наблюдаем нарушение контракта

Сравните безопасный поиск с прямым обращением по индексу:

TOPAZ
let tasks = ["Run first program", "Build application"]
print(tasks[2])

topaz run intentional-fault.tpz завершается с ненулевым кодом и указывает место в исходном файле:

Вывод
error[TPZ4001]: index 2 is out of bounds for an array of length 2
 --> intentional-fault.tpz:2:7
  |
2 | print(tasks[2])
  |       ^^^^^^^^

Ошибка выполнения — не None, не Err и не другое значение. Она прерывает вычисление, и её нельзя перехватить постфиксным ?, операторами необязательных значений или concurrent. Заведомо неверная константная арифметика может быть отклонена ещё при проверке; ошибка выполнения возникает, когда программа достигает неверного условия во время запуска.

Выбираем наблюдаемую модель неудачи

СитуацияЧто использовать или ожидать
Отсутствие значения является нормальнымOption, например None из get
Вызывающий код может отреагировать на причинуResult с Ok или Err
Выполняемый код нарушил контракт средыОшибка и ненулевой код процесса
Исходный код неверен до запускаСтатическая диагностика topaz check

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

Что остаётся устойчивым

Строки сравниваются как точные последовательности скаляров Unicode без неявной нормализации. Массивы сохраняют порядок элементов. Снимок ключей Map следует порядку вставки ключей, а операции коллекций — порядку, указанному в своём контракте. Номинальные значения сохраняют имя конструктора, когда этого требует каноническое отображение.

Реализации могут иметь разные внутренние представления лишь при одинаковом видимом результате; иначе цель должна явно отклонить программу. Это правило не превращает внутренние вспомогательные функции цели в открытый API Топаза.

Что намеренно не задано

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

Модель значений разобрана на странице Null, Option, Result и ошибки, тайм-ауты и границы порядка — на странице Конкурентность, а точная повседневная поверхность — в разделе Базовая библиотека.