Statements
Statements are the basic units of execution in Lattice. Unlike expressions, statements
do not produce values (or produce Unit). Lattice defines 12 statement forms.
Binding Statements
binding ::= phase_kw identifier [ ":" type_expr ] "=" expression phase_kw ::= "flux" | "fix" | "let"
A binding statement introduces a new variable into the current scope. The phase keyword determines the variable's mutability:
flux— The variable is mutable (fluid phase). It can be reassigned.fix— The variable is immutable (crystal phase). Reassignment is a runtime error.let— The phase is inferred from the initializer's phase tag.
flux counter = 0 // mutable fix PI = 3.14159 // immutable let name = "Lattice" // inferred // With type annotation flux items: Array = [] fix max: Int = 100
Assignment Statements
assignment ::= lvalue "=" expression lvalue ::= identifier | expression "." identifier | expression "[" expression "]"
Assignment statements update the value of an existing binding, struct field, or array/map
element. Assignment to a fix variable is a runtime error. Assignment produces Unit.
Compound Assignment
compound_assign ::= lvalue compound_op expression compound_op ::= "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>="
Compound assignment operators are syntactic sugar. The expression x += 1
is desugared to x = x + 1 at parse time. All 10 compound operators follow
this pattern.
flux x = 10 x += 5 // x = x + 5 → 15 x *= 2 // x = x * 2 → 30 x &= 0xFF // x = x & 0xFF
Destructuring Statements
destructure ::= phase_kw destruct_pattern "=" expression destruct_pattern ::= "[" array_pattern "]" | "{" struct_pattern "}" array_pattern ::= identifier { "," identifier } [ "," "..." identifier ] struct_pattern ::= identifier { "," identifier }
Destructuring binds multiple variables from a compound value in a single statement.
Array destructuring supports a rest element with ....
// Array destructuring let [first, second, ...rest] = [1, 2, 3, 4, 5] // first = 1, second = 2, rest = [3, 4, 5] // Struct destructuring let { x, y } = Point { x: 10, y: 20 } // x = 10, y = 20
Return Statements
return_stmt ::= "return" [ expression ]
A return statement exits the enclosing function with the given value, or Unit
if no expression is provided. Using return outside of a function is a parse error.
Break and Continue
break_stmt ::= "break" continue_stmt ::= "continue"
break exits the innermost enclosing loop. continue skips to the
next iteration of the innermost enclosing loop. Both are errors if used outside a loop.
Defer Statements
defer_stmt ::= "defer" block
A defer statement schedules a block to be executed when the enclosing scope exits, regardless of whether the exit is normal or due to an error. Multiple defers execute in LIFO (last-in, first-out) order.
fn process() { let fd = open("file.txt") defer { close(fd) } // runs last defer { print("cleanup") } // runs first // ... work with fd ... }
See Error Handling: Defer for details.
Expression Statements
Any expression can appear as a statement. The expression is evaluated and its value is discarded. This is commonly used for function calls that produce side effects.
Import Statements
import_stmt ::= "import" string_literal [ "as" identifier ] | "import" "{" import_list "}" "from" string_literal import_list ::= identifier { "," identifier }
Import statements load and execute another Lattice source file, making its exports available in the current scope. See Modules for details.
import "./utils.lat" as utils import { sin, cos, PI } from "./math.lat"
Lattice