Threadon / Structs

Structs

bundling values under one name

Defining a struct

A struct bundles several values into one. Think of it as a record, or a small object without methods.

Structs are declared with struct, a name, a colon, and a list of fields. Each field is a name, a colon, and a type.

struct Point:
    x: Int32
    y: Int32

Structs can only be declared at the top level of a file. They can't be declared inside a function.

Creating one

Create a struct by calling its name with named fields. Field order doesn't matter.

p: Point = Point(y=4, x=3)

Each field value must have the field's exact type. Passing a Float32 into an Int32 field is a compile error.

Give every field a value. The compiler lets you leave fields out, but the missing fields are not zeroed. They hold garbage. There is no warning.
p: Point = Point(x=3)   # compiles, but p.y is garbage

Always write every field in the initializer.

Reading and writing fields

Read a field with a dot. Write a field with a dot and =. Field assignment with plain = is allowed, unlike normal variable assignment.

def main() -> Int32
    p: Point = Point(x=3, y=4)
    print(p.x + p.y)
    p.x = 10
    print(p.x)
    return 0
7 10

You can also read a field in the middle of an expression: p.x + 1 works, and so does p.y = p.x + 1.

Nesting structs

A struct field can be another struct. Field access chains: p.z.z goes two levels down.

struct Z:
    z: Int32

struct P:
    x: Int32
    z: Z

def main() -> Int32
    p: P = P(x=1, z=Z(z=2))
    print(p.z.z)
    return 0
2

The nested struct is created with its own initializer, Z(z=2), inside the outer one.

Structs and functions

Structs can be passed to functions and returned from them. This is how you build real programs in Threadon. The full example is on the Examples page, but the shape is:

struct Point:
    x: Int32
    y: Int32

def length_sq(p: Point) -> Int32
    return p.x * p.x + p.y * p.y

def origin() -> Point
    return Point(x=0, y=0)

def main() -> Int32
    a: Point = Point(x=3, y=4)
    o: Point = origin()
    print(length_sq(a) + o.x)
    return 0
25

Structs as a workaround

Structs are a natural place to keep values you want to overwrite: update the fields with p.x = ..., and the change is visible wherever the struct value is used. (Plain = also works on a local variable, but field assignment is the way to mutate a struct's contents.)