Use this page as a map, not as a course or a compressed specification. Each card answers one practical question, shows the canonical shape, and points to the manual page that owns the details. If this is your first Topaz program, begin with the Learning path and keep this page open as a reference.
The everyday working set
Read across the cards when you want the whole language at a glance, or jump directly to the form you need. The examples are intentionally small: complete programs and declarations stand on their own; the module card names the one file it assumes.
Values, bindings, and types
Values are the data a program works with. Bind a value with const when it must be known at check time, let for an immutable local, or let mut when reassignment is part of the model. Add : Type when an annotation makes the contract clearer; otherwise Topaz infers it.
Shape: let name: Type = expression
const DEFAULT_MINUTES = 25
let title: string = "Check program"
let mut completed: int = 0
completed = completed + 1Manual: Types
Functions and lambdas
A named function gives reusable behavior an explicit parameter and result contract. A lambda is the compact anonymous form for passing behavior as a value. A function body may use return, or its last expression becomes the result.
Shape: function name(value: Type) -> Result { expression } and value => expression
function double(x: int) -> int {
x * 2
}
let increment: (int) -> int = x => x + 1
print("{double(increment(3))}")This program prints 8.
Manual: Functions & Generics
Operators and expression results
Operators combine values, while blocks, if, match, and value-position for can produce values of their own. In a block, the final expression has no trailing assignment or special return marker: it is simply the block result.
Shape: { statements; finalExpression }
let total = {
let base = 20
base + 5
}
print("{total}")This program prints 25. Assignment is a statement, not an expression.
Manual: Operators & Expressions
if, match, and for
Use if for a Boolean choice, match when the shape or case of a value matters, and for to visit values in order. Here for appears in value position, so it collects one result per score into an Array<string>.
Shape: if condition { value } else { value }, match value { case pattern => value }, and for item in values { value }
let scores = [92, 74]
let labels = for score in scores {
match score {
case 90..100 => "A"
case _ => if score >= 70 {
"pass"
} else {
"retry"
}
}
}labels is ["A", "pass"].
Manual: Patterns & Control Flow
Arrays, maps, and sets
Choose Array<T> for ordered values, Map<K, V> for key-to-value lookup, and Set<T> for unique values. Array order is positional; maps and sets retain their specified insertion order.
Shape: [a, b], map { key: value }, and set { a, b }
let scores: Array<int> = [80, 90]
let ids = set { 3, 1, 3 }
let labels = map { 1: "one", 2: "two" }
print("{scores}:{ids.toArray()}:{labels.keys}")The repeated 3 occupies one set slot. A map key appears only once in a literal.
Manual: Collections & Comprehensions
Records, enums, and unions
A record names a product with fields. An enum names a closed choice of variants. A union written with | says that one value may have any listed type; adding null is useful at a nullable data boundary.
Shape: record Name { fields }, enum Name { variants }, and type Choice = A | B
record Task {
title: string,
done: bool = false,
}
enum Filter {
All,
Open,
}
type Selection = Task | null
let selected: Selection = nullRecords and enums are nominal: their declared identity matters, not only their visible shape.
Manual: Records & Nominal Data
Absence, recoverable failure, faults, and cleanup
Use Option<T> for expected absence and Result<T, E> for a failure the caller can handle. Postfix ? unwraps Ok or returns the same Err. defer ties cleanup to a lexical scope. A fault is not a keyword or a value: it aborts evaluation and cannot be caught by ?.
Shape: Some(value) / None, Ok(value) / Err(error), result?, and defer { cleanup }
function readPlan(path: string) -> Result<string, string> {
let file = open(path)?
defer { file.close() }
file.read()
}An open or read failure stays in Result; an invalid array index is instead a runtime fault.
Manual: Null, Option, Result & Faults
Strings and registry-tag templates
Double-quoted strings interpolate with {expression}. The fixed registry tags p, r, sh, and sql preserve extra structure for paths, regular expressions, shell commands, and parameterized SQL. A tagged value does not automatically perform its host action.
Shape: "text {value}" and tag"text {value}"
let name = "Topaz"
let greeting = "Hello, {name}!"
let path = p"notes/{name}.txt"Backtick templates, dollar-brace interpolation, HTML tags, and user-defined tags are not current Topaz syntax.
Manual: Strings & Templates
Modules and visibility
Each .tpz file is one module. A dotted module path is relative to the compilation root. Imports form the file prologue, and only declarations marked export are visible to another module.
Shape: import module.path { Name } and export function name(...)
Assume src/plan.tpz exports StudyTask and summarize:
import src.plan { StudyTask, summarize }
export function summary(tasks: Array<StudyTask>) -> string {
summarize(tasks)
}The selected import exposes exactly the named declarations; it does not expose the module's private names.
Manual: Modules & Visibility
Format, check, test, run, and build
The toolchain applies one source and module model across authoring and delivery. Format first, make the static check pass, run tests, observe the program through the interpreter, then build the product target you intend to distribute.
Shape: topaz <task> [inputs]
topaz fmt --check --root .
topaz check --root . --locked
topaz test tests/plan.tpz --root . --locked
topaz run --root . --locked
topaz build --target python --root . --locked --out-dir build
check produces no artifact; run executes now; build creates a managed product and may require the selected target's host toolchain.
Manual: CLI & Diagnostics
Advanced routes
These forms matter once the ordinary working set is comfortable. They are intentionally quieter than the primary cards: follow only the branch your application needs.
- Pipelines — trace left-to-right value flow in Pipelines & Placeholders.
- Comprehensions — build collections with nested selection in Collections & Comprehensions.
- Protocols — learn static conformance beside nominal declarations in Records & Nominal Data.
- Generics — add one rank-1 type parameter when ordinary functions are not enough in Functions & Generics.
- Concurrency — join bounded work and choose a timeout result in Concurrency.
- Files and resources — cross an explicit host boundary in Files & Resources.
- Web and service products — choose a browser, offline, or bounded server path in Application Loop.
- Bytes and media — work with immutable
Bytes, mutableByteBuffer, hashes, and codecs in Core Library.
This page remains an unnumbered reference. Return to the Learning path when you want the concepts, exercises, and first complete application in dependency order.