Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Types

Primitive Types

Lake’s primitive types are:

TypeDescription
i6464-bit signed integer
strImmutable string literal (fat pointer: start + end addresses)
bufRuntime byte buffer (fat pointer: address + length)
pidProcess 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.