Basics

<!-- verified-against: seed-llvm; examples: docs-examples-test -->

Source text and names

.sd files are UTF-8. Strings/comments may contain Unicode; identifiers remain ASCII. Value names (functions, variables, fields, modules) use lower snake case; nominal types (structs, enums, unions, traits, generic params) and variants use UpperCamelCase; constants are upper snake case.

const MAX_ITEMS: usize = 64

fn main() -> i64 {
    // ação and 日本語 are valid comment text
    let greeting = "olá"
    (MAX_ITEMS + len(greeting)) as i64
}

The literal has static borrowed type str. Owned valid UTF-8 uses string. len returns byte length; Unicode scalar/grapheme operations belong in libraries.

Bindings

fn release(ticket: i64) {}

fn main() -> i64 {
    let answer = 42
    let mut count: usize = 0
    count += 1
    let linear ticket = 7
    release(ticket)
    answer + count as i64
}

Bindings are immutable by default. Mutation through a binding requires mut. linear creates an exactly-once consumption obligation.

Core types

Aggregates

struct Point { x: i64, y: i64 }

enum Color { Red Green Blue }

fn main() -> i64 {
    let origin = Point { x: 0, y: 0 }
    let selected = Color.Green
    match selected {
        Color.Green => origin.x
        Color.Red => origin.y
        Color.Blue => 0
    }
}

enum defines ADTs including payload-free enumerations. Raw unions require unsafe construction/access.

A repeat literal fills a fixed array from one literal:

fn layout() -> i64 {
    let slots: [4]usize = [0; 4]
    let bytes: [3]u8 = [255; 3]
    let grid: [2][3]i64 = [[0; 3]; 2]
    (slots[3] + bytes[2] as usize + grid[1][2] as usize) as i64
}

The element type comes from the annotation or the array's expected type, so no cast is needed. The value must be a literal (or a cast of one, or an array of those) — a place or call value is rejected (B048) rather than silently evaluated once per element — and the count must be a positive integer literal (B049) of at most 65536 (B050), because the elements are materialized individually; larger fills belong to a heap buffer or an explicit loop.

Expressions

Blocks, if, and match yield values. Use the final expression for an implicit result and return for early return. Integer arithmetic follows the deterministic rules in SEMANTIC_RULES.md; safe indexing remains checked in release builds.

The clean compiler implements typed phase-1/2 f"..." interpolation for text, bool, integers, floats, format specifications, and static display/debug traits. Use {{/}} for literal braces and .to_string()? only when an owned contiguous string is required. Printing remains an explicit library operation.