Runtime behavior matters when a program has checked successfully but its values, output, or failure still depend on execution. Start with what a user can observe: printed text, computed values, ordered collections, and a loud fault.
Observe ordinary values
Save this as runtime-behavior.tpz:
let values = [10, 20]
print("int: {7 / 2} {-7 % 3}")
print("float: {1.5 + 1.5}")
print("safe: {values.get(9)}")Run it with topaz run runtime-behavior.tpz:
int: 3 -1
float: 3.0
safe: Noneprint accepts a string. Interpolation renders the integer, floating-point,
and Option values before the call. There is no separate public println
prelude helper; use the exact print surface shown here.
An int is a signed 64-bit integer. Integer division truncates toward zero,
and the remainder follows the dividend’s sign. Runtime integer overflow and
division by zero fault instead of wrapping. A float is IEEE-754 binary64, so
it follows floating-point rather than decimal arithmetic.
values.get(9) returns None because a missing element is an ordinary
outcome for the safe lookup API.
Observe a violated contract
Contrast that lookup with direct indexing:
let tasks = ["Run first program", "Build application"]
print(tasks[2])topaz run intentional-fault.tpz exits nonzero and reports the source span:
error[TPZ4001]: index 2 is out of bounds for an array of length 2
--> intentional-fault.tpz:2:7
|
2 | print(tasks[2])
| ^^^^^^^^
A fault is not None, Err, or another value. It aborts evaluation and
cannot be caught by postfix ?, optional operators, or concurrent.
Constantly invalid arithmetic may instead be rejected during checking; the
runtime fault applies when the invalid condition is reached during execution.
Choose the observable failure model
| Situation | Use or expect |
|---|---|
| A value may normally be absent | An Option, such as get returning None |
| A caller can respond to a reason | A Result with Ok or Err |
| Executing code violates a runtime contract | A fault and nonzero process exit |
| Source is invalid before execution | A static diagnostic from topaz check |
Direct array access, dynamic integer division or remainder by zero, checked
integer overflow, a dynamic zero range step, a dynamically negative integer
exponent, and a runtime match miss are named fault sources. Prefer a safe
library operation when absence is part of the task.
What remains stable
String comparison uses exact Unicode scalar sequences without implicit normalization. Arrays preserve their element order. Map key snapshots use key insertion order, and collection operations preserve the order specified by their own contract. Nominal values keep their constructor identity when the canonical renderer requires it.
Different implementations may use different internal representations only when the visible result stays equal or the target declines loudly. This rule does not turn every helper used by a backend into a public Topaz API.
What is deliberately unspecified
Do not infer host integer wrapping, host hash order, locale-dependent number formatting, implicit Unicode normalization, catchable faults, cleanup after an abort, ambient filesystem or network authority, or performance guarantees. Concurrent arm order and output interleaving are intentionally unspecified.
Continue with Null, Option, Result & Faults for the value-level decision, Concurrency for timeout and ordering boundaries, and Core Library for the exact everyday helper surface.