Types
Primitive Types
Lake’s primitive types are:
| Type | Description |
|---|---|
i64 | 64-bit signed integer |
str | Immutable string literal (fat pointer: start + end addresses) |
buf | Runtime byte buffer (fat pointer: address + length) |
pid | Process identifier (fat pointer to process context) |
All values are represented as i64 at the machine code level. str literals
are stored as read-only data with fat pointers. A buf is a heap-allocated
byte buffer used for runtime data (file reads, network bytes, growable string
backing) — see the Standard Library std.bytes module for
bounded access. Process identifiers are heap pointers that remain stable for
the lifetime of the process.
Beyond the primitives, you can define your own records, enums, and generic types.
Type Annotations
Types appear in patterns:
n i64 # 64-bit integer
And in default values:
_ i64.0 # i64 with default value 0
Type-Based Dispatch
Types are central to branch dispatch. When a machine is called, the compiler matches the argument types against branch signatures:
counter is {
n i64 -> { ... } # matches calls with one i64 argument
}
The hash of argument types determines which branch receives the call. This dispatch is O(1) at runtime.
Process Identifiers (pid)
The pid type represents a handle to a spawned process. When a machine is called, it returns a pid that can be used to send messages to that process:
receiver is {
_ i64.0 -> {
wait { n i64 -> { rt_write(1 "got message\n" 12) } }
}
}
main is {
_ i64.0 -> {
let p pid = receiver()
p(42) # send message to receiver
}
}
A pid is a stable heap pointer that identifies the process for its entire lifetime. It can be stored in variables, passed as arguments, and sent through mailboxes.