Lake

Records

A record groups several named fields into one value. It is Lake's product type — the data half of the language, alongside enums.

§Declaring a record

A record is declared with the same is keyword as a machine, but its body lists field type pairs instead of branches:

lake
Point is {
  x i64
  y i64
}

§Constructing and reading

Construct a record by calling its name with positional arguments, in declaration order. Read a field with dot access:

lake
let p = Point(3 4)
let sum = p.x + p.y      # 7

Records are heap values addressed by a pointer-sized handle, so passing one around is cheap — you move a reference, not a copy of the fields.

§Records as machine arguments and results

Records flow through machines like any other value. A machine can take a record, read its fields, and return a new one:

lake
Rect is {
  w i64
  h i64
}

area is {
  r Rect -> ret i64 {
    ret r.w * r.h
  }
}

Here area is a returning machine (note the -> ret i64): it is called synchronously and yields a value, unlike a plain machine call which spawns a process. See state transitions for the distinction.

§Records and the type system

A record name is a nominal type: two records with identical fields but different names are different types, and a machine branch can dispatch on a record type just as it dispatches on i64 or buf. Records compose with generics (Vec[Point]), with enums (a variant may carry a record payload), and with protocols (a record may implement Eq, Show, …).

§Key ideas

  • A record is a product type: named fields, declared with Name is { f T … }.
  • Construct positionally (Point(3 4)); read with dot access (p.x).
  • Records are pointer-sized handles — cheap to pass.
  • Record names are nominal types and participate in branch dispatch, generics, enums and protocols.