Learn Topaz

Syntax at a Glance

A ten-minute map of everyday Topaz syntax and the exact manual page behind each form.

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

TOPAZ
const DEFAULT_MINUTES = 25
let title: string = "Check program"
let mut completed: int = 0
completed = completed + 1

Manual: 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

TOPAZ
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 }

TOPAZ
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 }

TOPAZ
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 }

TOPAZ
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

TOPAZ
record Task {
    title: string,
    done: bool = false,
}

enum Filter {
    All,
    Open,
}

type Selection = Task | null
let selected: Selection = null

Records 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 }

TOPAZ
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}"

TOPAZ
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:

TOPAZ
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]

BASH
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.

This page remains an unnumbered reference. Return to the Learning path when you want the concepts, exercises, and first complete application in dependency order.