Structs & Enums
User-defined compound types with named fields, and type-safe enumerations with named variants.
Structs
Structs are user-defined compound types declared with the struct keyword. Each struct has a fixed set of named fields.
Declaration
struct Point { x; y } struct Color { r; g; b; a }
Positional initialization
Supply values in the order the fields are declared. All fields must be provided.
var p = Point(10, 20) p.x // 10 p.y // 20 var c = Color(255, 128, 64, 255)
Named initialization
Use .field = value syntax for explicit field assignment. Fields can appear in any order. Unset fields default to null.
// Any order var p1 = Point{.y = 100, .x = 50} p1.x // 50 p1.y // 100 // Partial — unset fields are null var p2 = Point{.x = 7} p2.x // 7 p2.y // null
Field access and mutation
var p = Point(1, 2) // Read var sum = p.x + p.y // 3 // Mutate p.x = 99 p.y = p.y * 2 // 4 // Chained assignment p.x = p.y = 42 // both fields are now 42
Structs in collections
Structs can be stored in lists and maps, and their fields accessed through the collection.
// In a list var points = [Point(1, 2), Point(3, 4)] points[0].x // 1 points[1].y // 4 points[0].x = 99 // mutation through list access // In a map var named = { origin: Point(0, 0), unit: Point(1, 1) } named["origin"].x // 0 named["unit"].x = 10
Nested structs
Struct fields can hold other structs, creating nested structures.
struct Rect { topLeft; bottomRight } var rect = Rect(Point(0, 0), Point(100, 50)) rect.topLeft.x // 0 rect.bottomRight.y // 50 rect.topLeft.x = 10 // mutation through nesting
Structs with memory qualifiers
Structs interact with ref, val, slot, and clone just like any other type. See Memory Semantics for details.
func nudge(ref p) { p.x = p.x + 1 // modifies caller's struct } func safeCopy(val p) { p.x = 999 // local copy — caller unchanged return p } var origin = Point(0, 0) nudge(origin) // origin.x is now 1 var copy = safeCopy(origin) origin.x // still 1 copy.x // 999
Spread with structs
Use the spread operator to copy fields from an existing struct and selectively override them.
var p1 = Point{.x = 1, .y = 2} var p2 = Point{...p1, .y = 10} p2.x // 1 — copied from p1 p2.y // 10 — overridden
Schema scope hoisting
If you define a struct inside a function but return an instance of it, the schema is automatically pulled into the caller’s scope. This lets you keep the definition private while making the result usable anywhere.
func makePoint(x, y) { struct Point { x; y } // definition is scoped to this function return Point(x, y) // returning an instance hoists the schema } var p = makePoint(3, 4) p.x // 3 — the instance is fully usable p.y // 4
Enums
Enums are user-defined enumeration types declared with the enum keyword. Each enum has a fixed set of named variants.
Declaration and access
enum Color { RED, GREEN, BLUE } enum Status { ACTIVE, INACTIVE } var c = Color.RED var s = Status.ACTIVE
Enums can have any number of variants, including just one:
enum Days { MON, TUE, WED, THU, FRI, SAT, SUN } enum Single { ONLY }
Comparison and equality
Enum values of the same type can be compared with == and !=.
var a = Color.RED var b = Color.RED var c = Color.BLUE a == b // true a != c // true a == c // false // Assignment preserves equality var d = a a == d // true
Type safety
Different enum types are not comparable. Comparing variants from different enums is a type error.
enum Animal { DOG, CAT } enum Vehicle { CAR, BIKE } var a = Animal.DOG var v = Vehicle.CAR // a == v → type error! Different enum types
Enums in conditionals
Use enum comparisons to drive control flow.
enum Direction { UP, DOWN, LEFT, RIGHT } func describe(dir) { if (dir == Direction.UP) return "Going up" if (dir == Direction.DOWN) return "Going down" if (dir == Direction.LEFT) return "Going left" return "Going right" } describe(Direction.UP) // "Going up"
Enums in collections
Enum values can be stored in lists, maps, and struct fields.
enum Priority { LOW, MEDIUM, HIGH } // In a list var queue = [Priority.HIGH, Priority.LOW, Priority.MEDIUM] queue[0] == Priority.HIGH // true // In a map var config = { level: Priority.MEDIUM } config.level == Priority.MEDIUM // true // In a struct struct Task { name; priority } var task = Task("Deploy", Priority.HIGH) task.priority == Priority.HIGH // true
Enums with memory qualifiers
Enum values work with ref, val, slot, and clone like any other value type.
func promote(ref p) { if (p == Priority.LOW) p = Priority.MEDIUM else if (p == Priority.MEDIUM) p = Priority.HIGH } var level = Priority.LOW promote(level) level == Priority.MEDIUM // true — ref modified caller
Scoping
Enums follow normal scoping rules. An enum declared in an inner scope can shadow one in an outer scope.
enum Mode { ON, OFF } var m = Mode.ON { enum Mode { FAST, SLOW } // shadows outer Mode var inner = Mode.FAST // Mode.ON is not accessible here } // Outer Mode is restored m == Mode.ON // true
Like structs, if an enum is defined inside a function but an instance is returned, the schema is automatically hoisted to the caller’s scope.
func getStatus() { enum Status { OK, ERR } return Status.OK // schema hoisted on return } var s = getStatus() // s holds Status.OK