Records

Defining record types

A record type is declared with fields in an intented block, each on their own line.

main void() a point = 1, 2 log a.x b point = x: 1, y: 2 log b.y point record x float y float

Defining a record implicitly defines a new function.
In the above example, its signature would be: new point(x float, y float)
Like any new function, it can be called with either 1, 2 or x: 1, y: 2.
The record also implicitly defines functions for getting each field.
In the above example, these would have signatures of x float(a point) and y float(a point).

Short record syntax

For simple records, you can collapse the definition onto one line.

point record(x float, y float)

Empty records

The fields can be omitted, resulting in an empty type.

empty record

Arguments records

For functions with many arguments, you may want to make them a record:

main void() log foo x: 1, y: 2 foo-args record(x nat, y nat) foo nat(args foo-args) args.x + args.y

Mutable records

Any record fields marked with mut are mutable. As with mutable locals, the mut goes before the type.

main void() a mut-point = 1, 2 a.x := 3 log a.x mut-point record mut x mut float y mut float

a.x := 3 is a syntax equivalent to calling set-x a, 3.

Mutable record fields implicitly define setter functions.
In this case, they are set-x void(a point, value float) and set-y void(a point, value float).

Defining "new"

Since new functions are just ordinary functions, you can define additional new overloads.

main void() a point = () log a.x point record(x float, y float) new point() # This calls 'new point(x float, y float)' 0, 0

Named constructors

Defining a record also implicitly creates a function with the same name as the record and the same signature as new.

main void() log point 1, 2 point record(x float, y float) to json(a point)

point 1, 2 looks better than (1, 2)::point.
But if the type annotation is not necessary, prefer to write just 1, 2.