Learn Topaz

Syntax at a Glance

A ten-minute reference map covering everyday Topaz syntax and links to manual pages for each form.

Use this page as a quick reference map rather than a full course or a condensed specification. Each card answers one practical question, presents the canonical form, and points to the manual page detailing the underlying mechanics. If you are writing your first Topaz program, start with the Learning path and keep this page open for reference.

The everyday working set

Browse the cards to review syntax at a glance, or jump directly to the specific form you need. The examples are minimal by design. Complete programs and declarations stand on their own. The module card specifies the single file it assumes.

Values, bindings, and types

Values represent the data a program processes. Bind a value with const when it must be known at check time, let for an immutable local binding, or let mut when reassignment is part of the model. Add : Type when an explicit annotation clarifies the contract. Otherwise Topaz infers the type automatically.

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 defines reusable behavior with an explicit parameter and return contract. A lambda provides a concise anonymous form for passing behavior as a value. A function body can use return, or evaluate its final expression as 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. Inside a block, the final expression omits trailing assignments or return keywords and serves directly as 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 Boolean branching, match when the shape or case of a value matters, and for to iterate over values in sequence. Here for appears in value position, collecting each score result 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 evaluates to ["A", "pass"].

Manual: Patterns & Control Flow

Arrays, maps, and sets

Choose Array<T> for ordered values, Map<K, V> for key-to-value lookups, and Set<T> for unique elements. Array element ordering is index-based. 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 duplicate 3 occupies a single set slot. A map key appears only once in a literal.

Manual: Collections & Comprehensions

Records, enums, and unions

A record defines a product type with named fields. An enum defines a closed set of variants. A union written with | specifies that a value can match any listed type. Including null handles nullable data boundaries.

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 just their visible structure.

Manual: Records & Nominal Data

Absence, recoverable failure, faults, and cleanup

Use Option<T> for expected absence and Result<T, E> for recoverable errors that callers handle. Postfix ? unwraps Ok or returns the underlying Err. defer ties resource cleanup to the current lexical scope. A fault is neither a keyword nor a value. It aborts execution 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 yields a Result. An invalid array index produces a runtime fault instead.

Manual: Null, Option, Result & Faults

Strings and registry-tag templates

Double-quoted string literals interpolate expressions via {expression}. Built-in registry tags p, r, sh, and sql preserve domain structure for paths, regular expressions, shell commands, and parameterized SQL. A tagged value does not automatically trigger 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 part of current Topaz syntax.

Manual: Strings & Templates

Modules and visibility

Each .tpz file defines a module. A dotted module path resolves relative to the compilation root. Imports form the file prologue, and only declarations marked export are visible to external modules.

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 explicit import exposes only the named declarations. It does not expose private items of the module.

Manual: Modules & Visibility

Format, check, test, run, and build

The toolchain applies a consistent source and module model across development and distribution. Format source code first, verify that static checks pass, run tests, observe execution via the interpreter, and build the target binary or package.

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 immediately. build generates a managed build target and may require the selected target toolchain.

Manual: CLI & Diagnostics

Advanced routes

These forms become relevant once you are comfortable with the core working set. They are intentionally presented with less prominence than the primary cards. Follow only the paths your application requires.

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