Getting Started
OverviewLanguage GuideFull Reference
Book
Table of ContentsIntroductionPrefaceGetting StartedLanguage TourOwnershipErrorsConcurrencyStdlibNetworkingDataPackagesSpeed & SafetyCross-PlatformToolingCookbookAppendix
Reference
Standard LibraryKeywordsPerformanceSecurityBuilt-in FunctionsStatusDebuggingABI
How-To
Getting StartedHTTP APIsErrorsPackagesConcurrencyMemoryWASITestingRelease Builds
Project
RoadmapVisionChangelogContributing

Mako language guide

What works today — syntax and APIs the compiler accepts, with examples under examples/. Sources use the .mko extension (not .mk).

Doc Role
This guide Verified syntax + how to use it
The Mako Book Guided tour (idiomatic Mako)
STATUS.md Done matrix (adversarial)
BUILD.md Incremental cache, -j, residual clang
PERFORMANCE.md Release -O3 -flto, benchmarks
DEBUG.md lldb/gdb, dbg, sanitizers
SECURITY.md Memory safety + cache guarantees
STDLIB.md HTTP library + std surface
howto/ Task-oriented how-to guides
RELEASE.md Packaging / install
KEYWORDS.md Full reserved-keyword list
VISION.md North star
ROADMAP.md Sequencing

Legend: unmarked = verified · Target = aspirational (VISION Later). STATUS north-star / MVP: 100% (homebrew-core publish is the only external blocker).

Quickstart (install + init)

# From a checkout
make install                    # → ~/.local/bin/mako + ~/.local/share/mako/runtime
# or: ./scripts/install.sh

mako --version
mako init hello --name hello
cd hello
mako run main.mko               # uses installed runtime via binary-relative path
mako build main.mko             # binary named from mako.toml `name` when file is main.mko

# Backend API service scaffold
mako init mysvc --backend
cd mysvc
mako run main.mko

# Optional: multi-package workspace (local-only)
mako init myws --workspace
cd myws
mako check .
mako run -p app

mako version (also mako --version / -V) prints mako version mako0.1.0 darwin/arm64. Use mako version -v for an optional commit line. Override headers if needed: export MAKO_RUNTIME=/path/to/runtime.

Incremental builds are on by default (-j / MAKO_JOBS, --no-incremental to disable) — see BUILD.md. Release: mako build --release-O3 -flto (PERFORMANCE.md: optimized on microbenches).

For speed: pre-size make([]T, 0, n) / make(map[K]V, n), use arenas for request scope, prefer hold over share, measure with now_ns + ./scripts/bench.sh.

From a source tree without installing:

cargo run --release -- check examples/hello.mko
cargo run --release -- run examples/hello.mko

Packages (mako.toml)

Local path deps are the useful surface today; remote git fetch is thin (needs git).

mako pkg init mylib                 # same scaffold as `mako init`
mako pkg list                       # name + deps; path/git status on disk
mako pkg fetch                      # clone git deps into `.mako/deps/` (needs git + network)
mako pkg add helper ../helper       # record / update path dep in [dependencies]
mako pkg add path=../helper         # same; name from basename
mako pkg remove helper              # drop a [dependencies] entry
mako pkg lock                       # pin content_hash in mako.lock
mako pkg audit                      # offline advisory + license policy check

Example mako.toml dependency lines:

[dependencies]
"helper" = { path = "../helper", version = "0.1.0" }   # version is informational only
"tool" = { git = "https://example.com/tool.git", tag = "v0.1.0", version = "0.1.0" }

version on path deps is checked with SemVer (^ / ~ / exact) against the path’s mako.toml. Registry-only deps ("util" = { version = "^1.0.0" }) resolve from .mako/registry/<name>/<ver>/ (highest match) — see examples/pkg_registry/.

mako pkg list exits non-zero if a path dep is missing or a git dep is not under .mako/deps/ yet. mako check / build / run fail with the same MISSING wording (run mako pkg fetch first for git). Default CI does not live-fetch.

Local helpers:

mako pkg add helper ../helper
mako pkg add helper path=../helper
mako pkg add path=../helper          # name = directory basename
mako pkg add helper ../other         # idempotent: updates existing entry in place
mako pkg remove helper
mako pkg fetch                       # after declaring `{ git = "…", rev/tag/branch = "…" }`

Path deps at compile time

When you check / build / run a .mko under a project with mako.toml, local [dependencies] path entries are merged into the program (transitive: A→B→C walks each dep’s own mako.toml):

Dep layout What is included
Path to a .mko file That file
Package dir with lib.mko Only lib.mko (preferred)
Package dir without lib.mko All top-level .mko except tests (main stripped)

Symbols are namespaced by the dependency key declared by the parent package: "helper" = { path = "…" } → call helper.add(...) (same pattern as import "…" as helper). Nested packages keep the names their own manifests use (helper may call core.scale).

Demo: examples/pkg_path_dep/apphelpercore (mako run examples/pkg_path_dep/app/main.mko).

Workspace sketch (local-only)

Scaffold with mako init DIR --workspace (keeps default single-package mako init unchanged):

mako init myws --workspace
# → myws/mako.toml [workspace] members = ["lib", "app"]
# → myws/lib/lib.mko + myws/app/main.mko (path dep on lib)

Root mako.toml may also declare members by hand (no registry):

[workspace]
members = ["core", "helper", "app"]

From that root:

Command Behavior
mako check . Typecheck each member’s main.mko or lib.mko
mako build . Link each member that has main.mko (lib-only members skipped)
mako test . Run *_test.mko under members that have tests
mako fmt . / mako lint . Format / lint each member (optional -p)
mako bench . Run bench_*.mko under members that have benches (optional -p)
mako profile . -p app --json Build/run one member and report frontend/backend/run timings
mako run . Run the unique member with main.mko, or error asking for -p NAME
mako run -p app Run that member’s main.mko
mako check/build/test/fmt/lint/bench -p NAME Focus a single workspace member

Path deps between members still use [dependencies] path entries. See examples/pkg_path_dep/.


Keywords

Hard-reserved in src/lexer/mod.rs (always keywords, never identifiers). Full tables: KEYWORDS.md.

Category Keywords
Declarations fn struct enum actor receive interface extern const
Bindings / ownership let mut hold share as
Control flow if else while for in range break continue return defer match
Literals / logic true false and or not
Concurrency crew kick join fan select timeout default
Memory arena

Not keywords: type names (int, int8, int64, uint64, byte, float64, string, …), conversions T(x) / bytes(s), Ok/Err/assert*/t_run, len/cap/append/copy.


1. Hello and program structure

A program is a .mko file with top-level fn / struct / enum / actor / interface / const / extern "C". Entry point is fn main().

// examples/hello.mko
fn main() {
    print("hello from mako")
    print_int(fib(10))
}

fn fib(n: int) -> int {
    if n <= 1 {
        return n
    }
    return fib(n - 1) + fib(n - 2)
}

2. Types and strong typing

Built-in types

Type Notes
int Platform natural; C backend → int64_t, distinct in checker
int64 / int32 / int8 Fixed widths; int8(x) range-checks -128..127 at runtime
uint64 Unsigned 64-bit; reject negative on convert from signed
byte Unsigned 8-bit; element of []byte
float, bool, string No silent mix with ints
[]int / []int64 / []byte Slices (see § Slices / Bytes)
Option[T], Result[T, E] No nil
chan[T] Typed channels (chan[int] common)
Named structs / enums User-defined

Integer family

// examples/integers.mko · examples/bytes.mko
let a: int = 10
let b: int64 = 20
let c: int32 = 7
let d: int8 = int8(42)
let u: uint64 = uint64(7)
print_int64(int64(a) + b)
print_int8(d + int8(1))
// a + b  // error — cannot mix integer kinds

Rules:

Bad: examples/bad/int_mix_int64.mko, int32_mix_int64, int8_mix_int64.

Explicit conversions T(x)

// examples/convert.mko
let a: int = 10
let b = int64(a)
let f = float64(a)
print(string(a))           // "10"
let buf = bytes("hi")      // string → []byte
print(string(buf))
From \ To int family int8 uint64 byte float64 string []byte
int family int(x) int8(x) uint64(x) ✓≥0 byte(x) float64(x) string(x)
float64 truncates via int8 via uint64 via byte identity
string identity bytes(s)
[]byte index string(b) identity

floatfloat64 today. Prefer []byte(s) or bytes(s).

Compile-time range: constant int8(n) / byte(n) / uint64(n) checked at mako check; non-constants still runtime-abort.

Rules enforced today

Good: examples/types_ok.mko, examples/integers.mko. Intentional failures: examples/bad/*.mko (mako check must error).

fn add(a: int, b: int) -> int {
    return a + b
}

fn main() {
    let n: int = 1
    print_int(add(n, 2))
}

2c. Operators

Assignment is = only. Equality is == (never single =).

Class Operators
Compare == != < > <= >=
Logical && \|\| ! (also keywords and / or / not)
Arithmetic + - * / %
Bitwise & \| ^ &^ << >> · unary ^x (complement)
if x == 0 || y > 1 {
    return
}
let bits = (flags &^ mask) << 2
assert(!!ok)

2b. Slices

Literals [1, 2, 3] are slices (header: ptr, len, cap). Default element type is int; annotate for []int64 / []int32 / []byte:

let mut s = [1, 2, 3]              // []int
let mut a: []int64 = [10, 20, 30]  // []int64
let mut b: []byte = [72, 105]      // []byte

Type syntax: []T (preferred) or [T].

// examples/slice.mko · examples/slice64.mko · examples/bytes.mko
let mut s = [1, 2, 3]
print_int(len(s))
print_int(cap(s))

let t = s[1:3]      // shares backing store
t[0] = 99           // visible on s[1]
s = append(s, 4)    // may grow; assign result back

let n = copy(dst, s)   // returns count copied

// string <-> []byte (copying bridge)
let c = bytes("mako")     // helper
let d = []byte("mako")    // sugar (same as bytes())
print(string(c))
print(string(d[1:3]))

// pre-sized make
let s = make([]int, 3, 8) // len 3, cap 8
let z = make([]byte, 2)
let names = make([]string, 0, 4)
names = append(names, "mako")
let fs = make([]float, 2)          // examples/float_slice.mko
// also: let xs: []string = ["a", "b"]  · examples/str_slice.mko
Syntax Meaning
[…] / let b: []byte = […] Slice literal ([]int / []byte)
let xs: []string = ["a", "b"] or ["a","b"] String slice
let xs: []float = [1.0, 2.0] / make([]float, n[, cap]) Float slice
[]byte(s) or bytes(s) / string(b) String ↔ bytes conversion
make([]int\|[]byte\|[]string\|[]float, …) Pre-sized allocation
s[i:j], len/cap/append/copy Slice operations

Compile-time: int8(200) / byte(300) rejected at mako check when the arg is a constant (examples/bad/int8_literal_oor.mko, byte_literal_oor.mko). Runtime still aborts for non-const OOR.

append / copy are type-safe. Tests: slice_test, slice64_test, bytes_test, make_bytes_test, str_slice_test, float_slice_test.

Target / later: generic []T for structs; fuller monomorphization.


3. Functions and trailing returns

fn greet(name: string) -> string {
    return "hi " + name
}

fn area(w: int, h: int) -> int {
    // trailing expression = return (when no explicit return in body)
    match Ok(w * h) {
        Ok(v) => v,
        Err(e) => 0,
    }
}

void / omitted return: procedure. Missing return on a non-void function is a type error (examples/bad/missing_return.mko).


4. Control flow — while, for, range, break, continue, defer

// examples/while.mko · examples/range.mko · examples/break_continue.mko · examples/defer.mko
fn main() {
    let mut i = 0
    while i < 10 {
        i = i + 1
        if i < 3 { continue }
        if i > 5 { break }
        print_int(i)
    }

    let s = [10, 20, 30]
    for i, v in range s {  // index + value
        print_int(i)
        print_int(v)
    }
    for i in range s { }   // indices only
    for _, v in range s { } // values only (`_` is blank)
    for range s { }        // no binders

    for i in range 3 { }   // 0..2 (integer range)
    for j in 3 { }         // legacy: same as range n
    for v in s { }         // legacy: values only

    defer print("cleanup") // LIFO on exit / return; or `defer { … }`
    // NLL: defer bodies are checked at function exit — cannot use a moved `hold`
}

range over []int / []int64 / []byte / string.
On strings, for i, r in range s yields runes (Unicode code points as int); i is the byte offset.
len(s) / s[i] / s[i:j] stay byte-based. Use rune_count(s) for rune length.
break / continue only inside for / while (examples/bad/break_outside.mko). Labeled loops: outer: while … { break outer } / continue outer (examples/labeled_break.mko; unknown label → examples/bad/labeled_break_unknown.mko). Maps and channels: see §4c / §4e.


4b. Strings

UTF-8 text: byte view for len / index / slice; rune view for range / rune_count.

// examples/strings.mko
fn greet(name: string) -> string {
    return "hello, " + name
}

fn main() {
    let s = "hi\tthere\n"     // escapes: \n \t \r \\ \"
    print_int(len(s))         // byte length (== str_len(s))
    print_int(rune_count(s))  // Unicode code points
    print("ma" + "ko")        // concat → string
    if s == "x" { }           // == / != only (no < > on strings)

    let hello = "hello"
    print_int(int(hello[0]))  // s[i] → byte; convert to print
    print(hello[1:4])         // "ell" — byte substring

    let b = []byte("Hi!")     // or bytes(s)
    print(string(b))
    print(string(42))         // int → decimal string

    if str_eq("a", "a") { }
    if str_contains("hello", "ell") { }

    // range yields runes; index is byte offset
    for i, r in range "café" {
        print_int(i)
        print_int(r)          // é → 233
    }
}
Op Result Notes
"…" string \n \t \r \\ \"
s + t string concat
s == t / != bool no ordering
len(s) / str_len(s) int byte length
rune_count(s) int Unicode code points
s[i] byte bounds-checked; OOB aborts
s[i:j] / s[:j] / s[i:] / s[:] string byte slice (copy)
for i, r in range s runes; i = byte offset
[]byte(s) / bytes(s) []byte copy
string(b) / string(n) string from bytes / int
str_eq / str_contains bool helpers

Multibyte: len("café") is 5, rune_count("café") is 4. Index/slice are byte offsets.
OOB: examples/bad/string_index_oob.mko. Tests: strings_test.

Builder (growable buffer):

// examples/builder.mko
let mut b = str_builder()
builder_write(b, "ma")
builder_write(b, "ko")
builder_write_byte(b, byte(33))
print(builder_string(b))   // "mako!"
print_int(builder_len(b))

4c. Maps

Hash maps (open addressing in the runtime). Supported today: map[string]int, map[int]int, map[string]string.

// examples/map.mko
let mut m = make(map[string]int)
m["a"] = 1
print_int(m["a"])          // 1
print_int(m["missing"])    // 0 — zero value (no panic)
if has(m, "a") { }         // presence
let v, ok = m["a"]         // comma-ok pattern
if ok {
    print_int(v)
}
delete(m, "a")
print_int(len(m))

for k, v in range m {      // order unspecified
    print(k)
    print_int(v)
}

let mut mi = make(map[int]int)
mi[10] = 100

let mut ms = make(map[string]string)
ms["x"] = "hello"
Op Notes
make(map[K]V) / make(map[K]V, hint) allocate
m[k] = v / m[k] insert / get (missing → zero)
has(m, k) bool presence
let v, ok = m[k] comma-ok: value + present
delete(m, k) remove
len(m) entry count
for k, v in range m iteration; order unspecified

Wrong key type rejected at check (examples/bad/map_key_type.mko). Tests: map_test.


4c-2. Concurrent Maps (CMap)

CMap is a built-in concurrent hashmap designed for high-throughput key-value workloads. It uses lock-free reads and per-stripe spinlock writes (512 stripes, FNV-1a hash, 1M initial capacity). Safe to share across crew tasks without hold/share concerns.

// examples/cmap.mko
fn main() {
    let m = cmap_new()
    cmap_set(m, "hello", "world")
    print(cmap_get(m, "hello"))       // "world"
    print_int(cmap_has(m, "hello"))   // 1
    print_int(cmap_len(m))            // 1

    let new_val = cmap_incr(m, "counter", 5)   // atomic increment
    print_int(new_val)                          // 5

    print_int(cmap_del(m, "hello"))   // 1 (existed)
    print_int(cmap_len(m))            // 1 (only "counter" remains)
}
Op Notes
cmap_new() Create a new concurrent map
cmap_set(m, key, value) Set a key-value pair
cmap_get(m, key) Get value (returns "" if missing)
cmap_has(m, key) Check existence (1/0)
cmap_del(m, key) Delete key (returns 1 if existed)
cmap_len(m) Entry count
cmap_incr(m, key, delta) Atomic increment, returns new value

Thread-safe by design: multiple crew tasks can read and write the same CMap concurrently without channels or mutexes. Runtime: runtime/mako_cmap.h.


4d. UUID

RFC 4122 UUID v4 (CSPRNG: arc4random_buf on Apple, /dev/urandom elsewhere).

// examples/uuid.mko
let id = uuid_v4()
let s = uuid_string(id)       // "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
let id2 = uuid_parse(s)       // nil Uuid if invalid
if uuid_eq(id, id2) { }
if uuid_parse_ok(s) { }
if uuid_is_nil(uuid_nil()) { }
let r = uuid_check(s)         // Result[int, string]
match r {
    Ok(_) => print("valid")
    Err(e) => print(e)
}
API Result
uuid_v4() Uuid
uuid_string(u) canonical lowercase hex + hyphens (len 36)
uuid_parse(s) Uuid (nil on failure)
uuid_parse_ok(s) bool
uuid_eq / uuid_is_nil / uuid_nil compare / nil
uuid_check(s) Result[int, string]

Tests: uuid_test. Invalid: examples/bad/uuid_bad.mko.


4e. Range over channel

// examples/chan_range.mko
let ch = chan_new(4)
// … send then ch.close()
for v in range ch {   // recv until close
    print_int(v)
}

Requires range. Values only (for v in range ch). Ends when the channel is closed and drained.


5. Result, Option, ?, error(), match

No null. Failures are values.

// examples/result.mko
fn parse_positive(n: int) -> Result[int, string] {
    if n <= 0 {
        return error("must be positive")
    }
    return Ok(n)
}

fn double_positive(n: int) -> Result[int, string] {
    let v = parse_positive(n)?
    return Ok(v * 2)
}

fn show(r: Result[int, string]) -> int {
    match r {
        Ok(v) => v,
        Err(e) => -1,
    }
}
// examples/match.mko — Option + enums
fn option_or(o: Option[int], fallback: int) -> int {
    match o {
        Some(v) => v,
        None => fallback,
    }
}
// examples/wrap_err.mko · examples/errors_wrap.mko — wrap / is
let r = wrap_err(error("boom"), "parse")  // Err("parse: boom")
let ok = wrap_err(Ok(7), "unused")        // still Ok(7)
let e = errorf("missing %s", "config.toml")
assert(error_is(e, "config.toml"))
let msg = error_string(wrap_err(e, "load"))  // "load: missing config.toml"

Prefer Result + ? + wrap_err over abort for expected failures. Runtime aborts print a short message + debugger hint (DEBUG.md).

Unused Result as a statement is a compile error — use ?, match, or let _ = ….

Debug: dbg(n) / dbg_str(s) print [dbg] file:line: … on stderr (default builds use clang -g). See DEBUG.md.


6. Structs, enums, interfaces, generics

// examples/struct_slice.mko · nested_struct.mko · arena_struct.mko
struct Point {
    x: int
    y: int
}

let mut p = Point { x: 3, y: 4 }
print_int(p.x)
p.x = 10

let mut xs = make([]Point, 0, 4)
xs = append(xs, Point { x: 1, y: 2 })
let lit: []Point = [Point { x: 7, y: 8 }]

// Nested fields + assign
struct Addr { city: string zip: int }
struct Person { name: string addr: Addr }
let mut person = Person { name: "Ada", addr: Addr { city: "Paris", zip: 75001 } }
person.addr.city = "Lyon"

// Inside `arena a { … }`, `make([]Point, …)` and `append` grow from the arena
// (see examples/arena_struct.mko · arena_append.mko)
// examples/match.mko
enum Shape {
    Circle(int),
    Rect(int, int),
    Point,
}

fn describe(s: Shape) -> int {
    match s {
        Circle(r) => r * r,
        Rect(w, h) => w * h,
        Point => 0,
    }
}
// examples/generics_iface.mko · examples/iface_method.mko · examples/iface_self.mko
// examples/iface_dyn.mko · iface_multi.mko · iface_unit_dyn.mko
interface Writer {
    fn write(string) -> int
}

fn Writer_write(s: string) -> int {
    print(s)
    return str_len(s)
}

// Method sugar: `recv.write(s)` → `Writer_write(s)`
// With self: `fn Adder_add(self: Counter, delta: int)` → `c.add(5)` passes `c` first.
// Dyn: `let a: Adder = c` boxes; multi-concrete via `Adder_Counter_add` / `Adder_Doubler_add`.
// No-self dyn: `let w: Writer = 0` uses a unit vtable.
// examples/enum_method.mko — associated methods on enums
fn Shape_area(self: Shape) -> int { … }
print_int(Circle(5).area())

List[int] / Result[int, string] work; angle-bracket forms are accepted in places. Struct values, field assign, nested fields, and []Struct (including arena make + arena append) are supported. Interface methods are free functions Iface_method or Iface_Concrete_method with optional leading self; fat-pointer interface values box concrete receivers (or unit for no-self).


7. Ownership: let, mut, arena, hold, share

let x = 1
let mut y = 2
y = y + 1
// examples/arena.mko · examples/arena_slice.mko
arena a {
    // request-scoped work
    let mut s = make([]int, 3, 8)  // backing store from arena
    s[0] = 10
}

Inside arena name { … }, make([]int, …) / make([]byte, …) allocate from that arena (freed when the arena exits). Outside arenas, make uses the heap as before.

// examples/hold_move.mko — hold moves on rebind
hold let x = 7
hold let y = x
print_int(y)
// print_int(x)  // error: use of moved value `x`
// examples/hold_into_call.mko — hold moves into call args
fn id(n: int) -> int { return n }
hold let x = 42
print_int(id(x))
// print_int(x)  // error after move into id
// examples/hold_reassign.mko — assign into live hold before move
hold let mut x = 7
x = 9
print_int(x)

Intentional failures (must mako check error):

// examples/hold_partial.mko · hold_nested_partial.mko
hold let p = Point { x: 1, y: 2 }
let x = p.x   // moves only x
print_int(p.y) // y still usable

hold let o = Outer { inner: Inner { a: 1, b: 2 }, n: 9 }
let a = o.inner.a  // moves path "inner.a" only
print_int(o.inner.b)
// examples/ownership.mko — share RC seed
hold let a = 1
share let s = share_int(a)
print_int(share_get(s))
share_drop(s)

Hold reads: full reads of a non-Copy hold binding still consume it. Field access moves only that field path (hold_partial, nested o.inner.a). Shared-borrow seed: share let is immutable; share_int(x) blocks mutation of x until share_drop or block end (} auto-drops — share_nll), or mid-scope after the last use of the share binding in a straight-line block (share_mid_scope; bad share_mid_scope_live when still used later). If/else: share ended on both arms → mut after join OK (share_if_else_end); still live on both → conflict (examples/bad/share_if_else_live.mko). Diverging arms (return / break / continue): moves and share ends in a diverging arm do not poison code after the if (hold_if_return_ok; bad share_if_return_live when the skip-then path still borrows). Without else, a share that may survive on the skip-then path stays live (examples/bad/share_if_noelse_live.mko). While: shares introduced in the body end each iteration — re-borrow next iter OK (share_loop_iter; bad share_loop_live if outer share still used while mutating). for range restores share state the same way (share_for_iter; bad share_for_live). Nested if inside while: share ended on both arms → mut after if OK (share_nested_if_loop; bad examples/bad/share_nested_if_loop.mko). Match: share last-used on all arms → mut after match OK (share_match_arm; bad examples/bad/share_match_arm.mko). Diverging match arms (block that always returns / breaks / continues): moves and share ends on that arm do not poison code after the match (hold_match_return_ok; bad share_match_return_live, hold_match_return_after). CFG NLL (Done): if/else joins moves (union of non-diverging arms) — hold_if_else_branch / examples/bad/hold_if_else_after.mko; neither arm moves → hold_if_neither. Match arms join the same way (hold_match_arm / hold_match_after). While/for re-check the body only when some path can re-enter the header (continue or fall-through) — always-break bodies skip the second pass (hold_always_break_ok; still fail after move+break+use — hold_break_after_move). Nested always-break does not poison an outer hold (hold_nested_break_ok). Const-bool edge prune: if false / while false / dead continue arms do not move (hold_const_false_ok); if true takes only then (examples/bad/hold_const_true_after.mko). Loop-carried moves still fail (hold_loop_carried, hold_for_carried, hold_match_in_loop). break / continue: dead code after diverge (hold_break_ok, hold_continue_ok). Continue-path moves join next iter / post-loop (hold_continue_carried, hold_continue_next_iter, hold_for_continue_carried; OK — hold_continue_noll_ok). Share joins / mid-scope / diverge arms unchanged (share_* examples). Lambda/fan capture moves (hold_lambda_ok / hold_lambda_capture). Implementation: src/types/nll.rs + joins in src/types/mod.rs. Labeled break/continue shipped (label: while / break label). Residual: share is not full RC graphs.


8. Concurrency: crew, kick, join, fan, cancel

Jobs cannot outlive their crew.

// examples/concurrency.mko / channels.mko
fn main() {
    let ch = chan_new(4)
    crew t {
        let p = t.kick(producer(ch, 5))
        let c = t.kick(consumer(ch))
        let _ = p.join()
        print_int(c.join())
    }
}
// examples/parallel.mko
fn main() {
    let xs = [1, 2, 3, 4]
    let ys = fan(xs, |x| x * x)
    for v in ys {
        print_int(v)
    }
}
// examples/cancel.mko — cooperative cancel
crew t {
    // t.cancel() / t.cancelled()
}

9. Channels and select

let ch = chan_new(4)
let _ = ch.send(1)
let v = ch.recv()
ch.close()
// examples/select_default.mko — timeout + default + up to 16 arms
select timeout 30 {
    a => { print("got a") }
    b => { print("got b") }
    default => { print("default ok") }
}

Value of the ready arm: chan_select_value(). Fairness: round-robin when many are ready (examples/select_fair.mko). Helpers: chan_select2 / 3 / 4.


10. Actors

// examples/actor.mko
actor Session {
    receive Invite { print("invite") }
    receive Timer { print("tick") }
    receive Bye { print("bye") }
}

fn main() {
    let session = Session_spawn()
    crew t {
        let loopj = t.kick(Session_loop(session))
        let _ = Session_send(session, Session_Invite())
        let _ = Session_send(session, Session_Bye())
        print_int(loopj.join())
    }
}

Desugars to mailbox + crew loop. Bye / Stop end the loop by convention.


11. Networking

TCP

// examples/tcp_listen.mko, io_poll.mko
let fd = tcp_listen(18082)
let c = tcp_accept(fd)       // or tcp_accept_nb
let _ = tcp_write(c, "hi\n")
let _ = tcp_close(c)
let peer = tcp_connect("127.0.0.1", 18082)

HTTP/1.1 server (Done — beachhead, not a framework)

Sync handler surface: http_bindhttp_accept → read fields → http_respondhttp_close (one-shot) or http_next (keep-alive). Demos use a max-request loop + http_close_listener so the process exits. Smoke: ./scripts/http-server-smoke.sh.

Helper Meaning
http_bind(port) listen socket
http_accept(fd) accept + parse one request → conn id
http_method / http_path / http_header / http_body request fields
http_respond / http_respond_ct reply (ct sets Content-Type)
http_close(c) free conn slot (use after one-shot respond)
http_close_listener(fd) close listen socket (demo / graceful exit)
http_next / http_keepalive keep-alive loop
http_serve / http_echo fixed-body / echo helpers
http_get(url) plain HTTP/1.0 GET client (non-TLS)
// examples/http_server.mko — max N requests then exit (argv override)
fn main() {
    let mut max = 50
    let fd = http_bind(18100)
    let mut n = 0
    while n < max {
        let c = http_accept(fd)
        if c < 0 { /* skip */ } else {
            let p = http_path(c)
            if str_eq(p, "/health") {
                let _ = http_respond_ct(c, 200, "application/json", "{\"ok\":true}\n")
            } else {
                let _ = http_respond(c, 200, "hello from mako\n")
            }
            let _ = http_close(c)
            n = n + 1
        }
    }
    let _ = http_close_listener(fd)
}
mako build examples/http_server.mko -o out/http_server
out/http_server 5 &          # exit after 5 requests
curl -sS http://127.0.0.1:18100/health   # → {"ok":true}

Also: keep-alive (examples/http_keepalive.mko, http_headers.mko, http_routes.mko). Runtime reaps dead keep-alive peers on http_accept so one-shot servers do not fill the 32-slot conn table under curl.

HTTPS listener wrap (Done — OpenSSL when linked)

tls_serve_n(port, cert, key, body, max) — max-N HTTPS demo: /health → JSON, /body, else 404; then exits. Soft-fails (returns 1) without OpenSSL. Self-signed certs: runtime/certs/dev.crt + dev.key. Smoke skips when not linked: ./scripts/https-server-smoke.sh.

// examples/https_server.mko
let code = tls_serve_n(
    18443,
    "runtime/certs/dev.crt",
    "runtime/certs/dev.key",
    "hello from mako https\n",
    3
)
mako build examples/https_server.mko -o out/https_server
out/https_server &
curl -sk https://127.0.0.1:18443/health   # → {"ok":true}

Also: tls_serve / tls_serve_once (fixed body). Not a full HTTPS framework — no middleware, no ACME, no production TLS policy surface.

HTTP/2 TLS server (Done — OpenSSL + ALPN h2)

tls_serve_h2_routes(port, cert, key, root_body, health_body, max) — one TLS connection, ALPN h2, route / / /health, up to max streams, then exit. Smoke with curl --http2 (skips without OpenSSL / HTTP/2 curl): ./scripts/h2-server-smoke.sh.

// examples/h2_server.mko
let code = tls_serve_h2_routes(
    18446,
    "runtime/certs/dev.crt",
    "runtime/certs/dev.key",
    "hello from mako h2\n",
    "{\"ok\":true}\n",
    2
)
mako build examples/h2_server.mko -o out/h2_server
out/h2_server &
curl -sk --http2 https://127.0.0.1:18446/health https://127.0.0.1:18446/

Also: tls_serve_once_h2 / tls_serve_h2_n; gRPC-ish unary seed tls_serve_grpc_once / tls_grpc_unary (not grpcurl-complete). Not a full H2/gRPC server stack.

HTTP/2 seed (connection bootstrap + frames + 2-stream state; HPACK indexed/literal/dyn/Huffman): http2_client_preface / http2_server_preface / http2_settings_ack / http2_settings_max_concurrent (SETTINGS id 0x3) / http2_is_settings_ack, http2_detect, http2_empty_settings, http2_frame_*, http2_headers_frame / http2_data_frame / http2_continuation_frame, http2_stream_apply / http2_stream_apply_local / http2_stream_state_of / http2_stream_half_closed_remote / http2_stream_half_closed_local / http2_conn_reset / http2_conn_recv (HEADERS/DATA/RST SM + CONTINUATION assembly until END_HEADERS; non-ACK SETTINGS sets ack-needed; MAX_CONCURRENT_STREAMS enforced on new HEADERS; inbound DATA decreases stream+conn windows; reject DATA on idle / HEADERS on closed) / http2_conn_settings_ack_needed / http2_conn_auto_settings_ack (emit ACK frame + clear flag) / http2_conn_pump (recv multi-frame buffer + auto SETTINGS ACK and/or PING ACK if owed) / http2_conn_goaway_last (last-stream after GOAWAY; new streams > last rejected) / http2_conn_max_concurrent / http2_conn_active_streams / http2_conn_set_server / http2_conn_is_server (stream-id parity on new HEADERS) / http2_conn_header_block / http2_conn_header_stream / http2_conn_header_assembling / http2_conn_preface_received / http2_conn_settings_exchanged / http2_conn_closing, http2_window_of / http2_window_conn / http2_window_blocked / http2_window_consume / http2_window_increment, http2_goaway_frame / http2_ping_frame / http2_window_update_frame / http2_rst_stream_frame / http2_priority_frame / http2_push_promise_frame / http2_is_goaway / http2_is_ping / http2_is_window_update / http2_is_rst_stream / http2_is_priority / http2_is_push_promise / http2_goaway_last_stream / http2_goaway_error / http2_window_update_increment / http2_rst_stream_error / http2_priority_dep / http2_priority_weight / http2_priority_exclusive / http2_priority_apply / http2_stream_priority_dep / http2_stream_priority_weight / http2_stream_priority_exclusive / http2_stream_priority_child_count / http2_schedule_next (tree-aware: parent_weight×256+own; tie → lowest id) / http2_conn_recv also applies PRIORITY (exclusive reparent); RST aborts incomplete CONTINUATION / http2_push_promise_stream / http2_header_block (HEADERS+CONTINUATION merge), hpack_* / hpack_huffman_encode / hpack_huffman_decode / hpack_decode_block / hpack_decoded_count / hpack_decoded_name / hpack_decoded_value / hpack_decode_clear (indexed + literal-new-name). QUIC: quic_detect (long) / quic_long_header / quic_short_header / quic_long_type (0=Initial…3=Retry) / quic_is_retry / quic_is_version_negotiation / quic_vn_version_count / quic_vn_version_at / quic_vn_select (preferred or first) / quic_has_crypto / quic_crypto_offset / quic_crypto_data_offset / quic_crypto_data_len / quic_crypto_data (unprotected Initial CRYPTO) / quic_crypto_frame / quic_crypto_payload / quic_payload_crypto_data / quic_payload_crypto_data_len (build CRYPTO+PADDING; parse after decrypt) / quic_ack_frame / quic_ack_largest / quic_ack_delay / quic_ack_range_count / quic_ack_first_range / quic_ack_smallest / quic_is_ack (ACK type=0x02 single-range seed; 1-byte varints only) / quic_stream_frame / quic_is_stream / quic_stream_id_of / quic_stream_offset / quic_stream_fin / quic_stream_data / quic_stream_data_len (STREAM type 0x08–0x0f seed; 1-byte varints) / quic_spin_bit / quic_key_phase / quic_version / quic_dcid_len / quic_dcid / quic_scid_len / quic_scid / quic_payload_offset / quic_hkdf_expand_label / quic_hkdf_expand_label_hex (HKDF-Expand-Label demo for initial secrets — not full QUIC protection) / quic_initial_client_secret / quic_initial_client_secret_hex / quic_initial_client_key / quic_initial_client_iv / quic_initial_client_hp (+ _hex) / quic_initial_protect / quic_initial_unprotect (AES-GCM payload AEAD from initial client secret; AAD = caller header) / quic_header_protection_mask / quic_initial_hp_mask (+ _hex) / quic_header_protect_apply / quic_header_protect_remove / quic_initial_packet_protect / quic_initial_packet_unprotect (minimal protected Initial assemble/decode; CRYPTO-in-payload roundtrip seed — not full A.2 1162-byte CRYPTO/PADDING sample) / hex_decode (RFC 9001 §5.2 from dest CID + v1 salt; Appendix A.1 key/iv/hp KATs). TLS record: tls_record_*. Buffer AEAD: tls_aead_seal / tls_aead_open (AES-128-GCM; not record AEAD). Record seed: tls_record_appdata_seal / tls_record_appdata_open (type=23 + 0x0303 header; AAD = 5-byte header). Seq nonce: tls_record_appdata_seal_seq / open_seq (IV XOR seq into last 8 bytes; tls_record_seq_reset / write_seq / read_seq). Handshake seed: tls_client_hello / tls_client_hello_random / tls_client_hello_legacy_version / tls_client_hello_has_aes128_gcm / tls_server_hello / tls_server_hello_random / tls_encrypted_extensions / tls_finished / tls_certificate / tls_certificate_der / tls_certificate_verify / tls_certificate_verify_scheme / tls_certificate_verify_sig / tls_finished_verify_data / tls_finished_verify_data_hex / tls_transcript_reset / tls_transcript_append / tls_transcript_len / tls_transcript_finished_hex / tls_hs_reset / tls_hs_state / tls_hs_advance / tls_hs_is_app / tls_hs_msg_type / tls_hs_session_reset / tls_hs_session_feed / tls_hs_session_client_hello / tls_hs_session_server_hello / tls_hs_session_encrypted_extensions / tls_hs_session_certificate / tls_hs_session_certificate_verify / tls_hs_session_finished / tls_hs_session_finished_hex (session wires CH→…→Finished into SM + transcript — not a live handshake) / tls_derive_secret / tls_derive_secret_hex / tls_client_handshake_traffic_secret / tls_server_handshake_traffic_secret (+ _hex) / tls_client_application_traffic_secret / tls_server_application_traffic_secret (+ _hex) (Derive-Secret / traffic-secret demos — not a live handshake).

Protobuf / gRPC wire seed: pb_encode_* / pb_simple_* / nested / repeated, grpc_encode_message / grpc_message_* / grpc_message_within_limit / grpc_default_max_message (4 MiB default), grpc_unary_*, grpc_http2_unary / grpc_http2_unary_payload / grpc_http2_unary_response / grpc_http2_unary_response_status / grpc_http2_response_payload / grpc_http2_response_status (HEADERS+DATA+trailer HEADERS buffer → grpc-status; trailer-only → -1), grpc_http2_stream_data / grpc_http2_stream_two / grpc_http2_stream_data_count (streaming DATA with/without END_STREAM seed), grpc_http2_client_stream_flow (two client DATA + server response/status one-flow seed), grpc_content_type / grpc_status_trailer / grpc_status_code. Round-trip example: examples/grpc_unary_roundtrip.mko.

Postgres (libpq when linked): pg_connect / pg_ok / pg_exec / pg_close / pg_exec_row_count / pg_connect_urlpg_ok==0 when server down or no libpq (never fake success); pg_exec / pg_exec_row_count return -1 when disconnected; pg_close is a no-op on handle 0; pg_connect_url parses postgres://… to libpq keywords (no connect).

TLS

Production integration started (Homebrew OpenSSL when MAKO_HAS_OPENSSL): live handshake + verified GET/POST + ALPN h2 GET — not a full TLS/HTTP2 stack yet. See TLS_LIVE.md for opt-in live tests (MAKO_LIVE_TLS=1).

// Live path (examples/testing/tls_live_test.mko — set MAKO_LIVE_TLS=1):
//   tls_serve_once / tls_serve_n / tls_serve_once_h2
//   tls_serve_n — max-N HTTPS demo (/health JSON); examples/https_server.mko
//   tls_handshake_ok / tls_handshake_version  — SSL_connect + peer verify
//   tls_get / tls_post / tls_get_insecure     — HTTPS/1.1
//   tls_h2_settings_exchange                  — ALPN h2 + SETTINGS
//   tls_h2_get / tls_h2_post                  — HEADERS+DATA, returns "200\\n<body>"
//   tls_h2_get_twice / tls_serve_h2_n         — keep-alive second request (streams 1+3)
//   tls_h2_mux / tls_serve_h2_routes          — overlapping `/` + `/health` multiplex
//   tls_serve_grpc_once / tls_grpc_unary      — gRPC-ish unary over h2 (echo + grpc-status)
//   tls_serve_grpc_stream / tls_grpc_stream   — 2 client DATA → 2 echoed DATA + trailer
//   tls_serve_h2_wu / tls_h2_window_get       — WINDOW_UPDATE on wire + GET continues
//   nghttp2_available / nghttp2_get / nghttp2_post / nghttp2_get_two — real libnghttp2 (when linked)
//   quiche_available / quiche_version / quiche_handshake / quiche_h3_get / quiche_h3_post / quiche_h3_get_two
// Demos: examples/tls_once.mko, tls_verify.mko, tls_client.mko
// Certs: runtime/certs/dev.crt (CN=localhost), runtime/certs/dev.key
// Next: runtime/third_party (nghttp2 linked; quiche needs Rust FFI)

Secure defaults (OpenSSL path): TLS 1.2+, modern cipher suites, no compression. tls_get / tls_post verify peers; tls_get_insecure skips verify for local demos. When libnghttp2 is detected, prefer nghttp2_get / nghttp2_post for production-shaped h2 clients.

Building APIs

Mako is a backend language: HTTP handlers, JSON, routing, and service templates. How-to: howto/02-http-apis.md · STDLIB: STDLIB.md.

mako init mysvc --backend    # scaffold main.mko + README
# or study: examples/api_backend/ · examples/http_lib/

HTTP library (HTTP/1.1 builtins):

Builtin Role
http_bind / http_accept / http_close Listen loop
http_method / http_path / http_body / http_header Request
http_respond / http_respond_ct / http_respond_json Response
http_get / http_post / http_request Client
http_get_timeout / http_post_timeout Client + timeout
http_last_status / http_last_header Last client response meta
json_* / json_object_from_map_ss Encode/decode glue
let c = http_accept(fd)
if str_eq(http_path(c), "/health") {
    let _ = http_respond_json(c, 200, "{\"ok\":true}\n")
}
let _ = http_close(c)
let body = http_get("http://127.0.0.1:8080/health")
print_int(http_last_status())

Smoke: ./scripts/http-lib-smoke.sh · HTTPS/H2: examples/https_server.mko, examples/h2_server.mko.

Direct I/O (mako_dio.h)

Low-level unbuffered file operations and memory-mapped files for storage engines, databases, and performance-critical I/O paths. Runtime: runtime/mako_dio.h.

// examples/dio_write.mko — positional read/write without buffering
fn main() {
    let fd = file_open("/tmp/mako_dio.dat", 1, 0)  // mode=write
    let _ = fallocate(fd, 4096)                     // pre-allocate space
    let _ = pwrite(fd, "hello dio", 0)              // write at offset 0
    let _ = fdatasync(fd)                           // flush data to disk
    let _ = file_close(fd)

    let fd2 = file_open("/tmp/mako_dio.dat", 0, 0)  // mode=read
    let data = pread(fd2, 9, 0)                      // read 9 bytes at offset 0
    print(data)                                      // "hello dio"
    print_int(file_size(fd2))
    let _ = file_close(fd2)
}
Op Signature Notes
file_open(path, mode, flags) -> int Open fd; mode 0=read, 1=write, 2=rw
file_close(fd) -> int Close fd
pread(fd, count, offset) -> string Positional read (no seek)
pwrite(fd, data, offset) -> int Positional write (no seek)
file_append(fd, data) -> int Append to file
fsync(fd) -> int Flush data + metadata
fdatasync(fd) -> int Flush data only
fallocate(fd, size) -> int Pre-allocate disk space
file_size(fd) -> int File size in bytes
file_truncate(fd, size) -> int Truncate file
file_seek(fd, offset, whence) -> int Seek; whence 0=SET,1=CUR,2=END
file_read_exact(fd, n) -> string Read exactly n bytes or fail

Memory-mapped files (MMap)

// examples/mmap_kv.mko — memory-mapped file for fast random access
fn main() {
    let m = mmap_create("/tmp/mako.mmap", 4096)
    let _ = mmap_write(m, 0, "key1=value1\n")
    let _ = mmap_sync(m, 0)
    let data = mmap_read(m, 0, 12)
    print(data)                       // "key1=value1\n"
    print_int(mmap_size(m))           // 4096
    let _ = mmap_close(m)

    // Re-open existing mapping
    let m2 = mmap_open("/tmp/mako.mmap", 0)
    let data2 = mmap_read(m2, 0, 12)
    print(data2)
    let _ = mmap_close(m2)
}
Op Signature Notes
mmap_open(path, mode) -> MMap Map existing file
mmap_create(path, size) -> MMap Create + map new file
mmap_read(m, offset, count) -> string Read from mapping
mmap_write(m, offset, data) -> int Write to mapping
mmap_sync(m, flags) -> int Flush mapping to disk
mmap_size(m) -> int Size of mapping
mmap_close(m) -> int Unmap and close

Binary Buffer (Buf type)

The Buf type provides structured reading and writing of binary data — useful for network protocols, file formats, and serialization. Runtime: runtime/mako_buf.h.

// examples/buf_protocol.mko — build and parse a binary message
fn main() {
    // Pack a message: u8 type + u32 length + payload
    let b = buf_pack_new(64)
    buf_write_u8(b, 1)                 // message type
    buf_write_u32(b, 5)                // payload length
    buf_write_str(b, "hello")          // payload
    let wire = buf_to_string(b)
    buf_free(b)

    // Parse it back
    let r = buf_from_string(wire)
    let msg_type = buf_read_u8(r)
    let msg_len = buf_read_u32(r)
    let payload = buf_read_str(r, msg_len)
    print_int(msg_type)                // 1
    print_int(msg_len)                 // 5
    print(payload)                     // "hello"
    buf_free(r)
}
Op Notes
buf_pack_new(capacity) New write buffer
buf_from_string(s) Buffer from existing bytes
buf_to_string(b) Extract contents as string
buf_len(b) / buf_pos(b) Total length / current position
buf_reset(b) / buf_seek(b, pos) Reset to start / seek to position
buf_free(b) Free buffer memory
buf_write_u8/u16/u32/u64 Write unsigned integers (little-endian)
buf_write_i32/f32/f64 Write signed int / floats
buf_write_u16be/u32be Write big-endian unsigned
buf_read_u8/u16/u32/u64 Read unsigned integers (little-endian)
buf_read_i32/f32/f64 Read signed int / floats
buf_read_u16be/u32be Read big-endian unsigned
buf_write_bytes(b, data) / buf_write_str(b, s) Write raw bytes/string
buf_read_bytes(b, n) / buf_read_str(b, n) Read n raw bytes/string

Systems programming

Ownership (hold/share), arenas, bytes, and files — no mandatory GC:

Pattern Example
Arenas examples/arena.mko, arena_struct.mko
Hold / NLL examples/hold_*.mko, docs/LANGUAGE.md
Bytes / FS examples/bytes.mko, file_env.mko; append_file for logs
Append log examples/systems_log/
FFI examples/extern_c.mko

Building databases / storage engines

Beyond SQL clients (SQLite/Postgres): ship a mini embedded engine in Mako.

Piece Path
Append-only KV (PUT/DEL log, replay) examples/db_engine/
Tests examples/testing/db_engine_test.mko
SQL clients §14 below
mako run examples/db_engine/main.mko
mako test examples/testing/db_engine_test.mko

Buffer AEAD (AES-128-GCM via OpenSSL — not TLS record AEAD / handshake): tls_aead_seal(key16, nonce12, plaintext, aad) → ciphertext||tag(16); tls_aead_open(...) → plaintext or empty on auth fail (examples/testing/tls_aead_test.mko).

TLS 1.3-like application_data record seed (header + AEAD, AAD = 5-byte header): tls_record_appdata_seal / tls_record_appdata_open; seq variants tls_record_appdata_seal_seq / open_seq. Handshake seed helpers (tls_client_hello / hs_session / traffic secrets) remain unit-test seeds — prefer the live OpenSSL builtins above for integration.

WebSocket

// examples/ws_echo.mko, ws_ping.mko
// RFC6455 upgrade + text; ping/pong + binary

11b. Event Loop (Non-blocking I/O)

Mako provides a high-performance event loop for non-blocking I/O multiplexing (uses epoll on Linux, kqueue on macOS under the hood). Runtime: runtime/mako_evloop.h.

Event Loop Core

// Create and use an event loop
let el = evloop_new()
let server_fd = nb_listen(8080)
let _ = evloop_add(el, server_fd, 1)  // 1 = readable

while true {
    let n = evloop_wait(el, 1000)  // wait up to 1000ms
    let mut i = 0
    while i < n {
        let fd = evloop_event_fd(el, i)
        let flags = evloop_event_flags(el, i)
        if fd == server_fd {
            let client = nb_accept(server_fd)
            let _ = evloop_add(el, client, 1)
        } else {
            let data = nb_read(fd)
            let _ = nb_write(fd, "HTTP/1.1 200 OK\r\n\r\nhi\n")
            let _ = evloop_del(el, fd)
            let _ = nb_close(fd)
        }
        i = i + 1
    }
}
let _ = evloop_close(el)
Function Purpose
evloop_new() Create event loop
evloop_add(el, fd, flags) Register fd for monitoring
evloop_mod(el, fd, flags) Modify interest flags
evloop_del(el, fd) Remove fd from monitoring
evloop_wait(el, timeout_ms) Wait for events, returns count
evloop_event_fd(el, index) Get fd from ready event
evloop_event_flags(el, index) Get flags from ready event
evloop_close(el) Destroy event loop

Non-blocking Socket Helpers

Function Purpose
nb_listen(port) Non-blocking TCP listener
nb_accept(fd) Non-blocking accept
nb_read(fd) Non-blocking read
nb_write(fd, data) Non-blocking write
nb_udp_bind(port) Non-blocking UDP socket
nb_udp_recv(fd) Non-blocking UDP receive
nb_close(fd) Close non-blocking socket

11c. Game UDP

High-performance UDP networking for game servers. Runtime: runtime/mako_game.h.

let u = game_udp_bind(27015)
let el = evloop_new()
let _ = evloop_add(el, game_udp_fd(u), 1)

while true {
    let n = evloop_wait(el, 16)  // ~60 Hz
    if n > 0 {
        let data = game_udp_recv(u)
        let peer = game_udp_sender(u)
        let _ = game_udp_broadcast(u, "state:" + data)
    }
}
game_udp_close(u)
Function Purpose
game_udp_bind(port) Bind UDP game socket
game_udp_recv(u) Receive packet (tracks sender)
game_udp_sender(u) Get peer ID of last sender
game_udp_send(u, peer, data) Send to specific peer
game_udp_broadcast(u, data) Send to all connected peers
game_udp_kick(u, peer) Disconnect a peer
game_udp_peers(u) Number of connected peers
game_udp_fd(u) Raw fd for event loop integration
game_udp_close(u) Close socket
tick_now_us() Microsecond timestamp for game ticks
tick_sleep_us(start_us, interval_us) Sleep to maintain tick rate

11d. Cloud / Distributed Primitives

Primitives for building distributed services. Runtime: runtime/mako_cloud.h.

Consistent Hashing

let ring = chash_new(3, 150)  // 3 nodes, 150 virtual nodes each
let node = chash_get(ring, "user:42")
print_int(node)  // 0, 1, or 2

let new_id = chash_add_node(ring)
chash_remove_node(ring, 0)
print_int(chash_node_count(ring))  // 3
chash_free(ring)
Function Purpose
chash_new(nodes, vnodes) Create hash ring
chash_get(ring, key) Get node for key
chash_add_node(ring) Add node, returns ID
chash_remove_node(ring, node) Remove node
chash_node_count(ring) Active node count
chash_free(ring) Destroy ring

Rate Limiter

let rl = ratelimit_new(100, 10)  // 100 tokens/sec, burst of 10
if ratelimit_allow(rl) == 1 {
    // request allowed
}
print_int(ratelimit_remaining(rl))
ratelimit_free(rl)
Function Purpose
ratelimit_new(rate, burst) Token bucket limiter
ratelimit_allow(r) Consume token (1=allowed, 0=rejected)
ratelimit_remaining(r) Tokens remaining
ratelimit_free(r) Destroy

Circuit Breaker

let cb = breaker_new(5, 30000, 3)  // 5 failures, 30s timeout, 3 half-open max
if breaker_allow(cb) == 1 {
    // attempt request
    breaker_success(cb)
} else {
    // circuit is open, fail fast
}
print_int(breaker_state(cb))  // 0=closed, 1=open, 2=half-open
breaker_free(cb)
Function Purpose
breaker_new(threshold, timeout_ms, half_open_max) Create circuit breaker
breaker_allow(cb) Check if request should proceed
breaker_success(cb) Record success
breaker_failure(cb) Record failure
breaker_state(cb) 0=closed, 1=open, 2=half-open
breaker_reset(cb) Reset to closed
breaker_free(cb) Destroy

11e. HTTP Engine

High-level HTTP server with declarative routing. Runtime: runtime/mako_httpengine.h.

let e = httpengine_new()
let _ = httpengine_route(e, "GET", "/health", 1)
let _ = httpengine_route(e, "POST", "/api/users", 2)
let _ = httpengine_start(e, 8080)
// Engine runs until stopped
httpengine_stop(e)
httpengine_free(e)
Function Purpose
httpengine_new() Create HTTP engine
httpengine_route(e, method, path, handler_id) Register route
httpengine_start(e, port) Start listening
httpengine_stop(e) Stop engine
httpengine_free(e) Destroy engine

12. Async I/O (colorless)

Ordinary functions; runtime uses select / kqueue / epoll underneath. No async/await keywords.

// examples/io_wait.mko
let ready = io_wait(fd, 50)          // 1 ready, 0 timeout

// examples/io_poll.mko / io_poll4.mko
let which = io_poll2(a, b, 500)      // index or -1
let which4 = io_poll4(a, b, c, d, 40)

// examples/io_kq.mko / io_native.mko
let w = io_kq_poll2(a, b, 500)       // Darwin kqueue
let n = io_native_poll2(a, b, 500)   // kqueue | epoll | select

Linux epoll is compiled under #ifdef __linux__ (io_epoll_poll2).


13. JSON and #[derive(json)]

// examples/derive_json.mko
#[derive(json)]
struct Person {
    name: string
    age: int
}

fn main() {
    let j = Person_to_json("Ada", 36)
    let name = Person_name_from_json(j)
    let age = Person_age_from_json(j)
}
// examples/json_nested.mko, json_array.mko, json_map.mko
let nested = json_nest("addr", addr)
let doc = json_merge(person, nested)
let city = json_path_string(doc, "addr", "city")
let nums = json_array_ints3(10, 20, 30)
let more = json_array_push_int(nums, 40)
let names = json_array_push_string(json_array_strings2("a", "b"), "c")
let mut m = make(map[string]string, 4)
m["k"] = "v"
let obj = json_object_from_map_ss(m)

Also: json_object, json_si / json_ss / json_i, json_get_string / json_get_int, json_get_object, json_array_len, json_array_get_*.

const comptime fold: const PORT = 10 * 100 + 80 / 2 (examples/derive_json.mko).


14. SQLite and Redis

// examples/sqlite.mko — needs libsqlite3
let n = sqlite_query_int("file.db", "select 42")
let s = sqlite_query_text("file.db", "select 'hi'")
// examples/redis_ping.mko — RESP PING; mock if no redis-server
crew t {
    let s = t.kick(redis_mock_once(16379))
    sleep_ms(40)
    let r = redis_ping("127.0.0.1", 16379)  // "PONG"
    let _ = s.join()
}
// SET/GET/DEL/EXISTS: redis_set / redis_get / redis_del / redis_exists + redis_mock_kv
// (examples/testing/redis_kv_test.mko)

Unified SQL facade (sql_open_sqlite / sql_open_postgresSqlDB):

let db = sql_open_sqlite("/tmp/app.db")

// DDL or simple statements (no parameters)
let _ = sql_exec_plain(db, "CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT, email TEXT)")

// Insert with up to 4 string parameters ($1..$4 for Postgres, ? for SQLite)
let _ = sql_exec_str4(db, "INSERT INTO users(name, email, '', '') VALUES ($1, $2, $3, $4)", "Ada", "ada@example.com", "", "")

// Query a single string value (first column, first row)
let name = sql_query_str(db, "SELECT name FROM users WHERE email = $1", "ada@example.com")
print(name)  // Ada

sql_close(db)

sql_exec_plain returns 0 on success; sql_exec_str4 returns 0 on success (uses parameterized queries for safety); sql_query_str returns "" if no rows match. These complement sql_exec(db, sql, []int) which only supports integer parameters.

Postgres: libpq pg_connect is available (fails gracefully when server down). pg_connect_url parses URLs; pg_exec_row_count returns -1 when disconnected.

Live Docker fixtures (ephemeral; tear down after): scripts/ci-redis.shexamples/ci/redis_live.mko (PING/SET/GET/DEL on :6380); scripts/ci-postgres.shexamples/ci/pg_live.mko (pg_ok/pg_exec on :5433). Default suite still uses mocks / down-server asserts (no Docker required).

Time / path / file / env / args / log helpers (stdlib — full index: STDLIB.md):

// examples/stdlib/demo.mko · testing/stdlib_*_test.mko · path_join.mko · …
let p = path_join("foo", "bar")  // "foo/bar"
assert_eq_str(path_clean("/a/../b"), "/b")
assert_eq_str(str_join(str_split("a,b", ","), "-"), "a-b")
assert_eq_str(fmt_sprintf("hi %s", "mako"), "hi mako")
let t = now_ms()                 // wall clock ms
let ns = now_ns()                // monotonic ns (benches)
let x = black_box(x)             // prevent LTO from erasing bench work
sleep_ms(1)
print(time_format(t))            // RFC3339 UTC
let _ = mkdir("/tmp/d")
let _ = write_file("/tmp/d/x.txt", "hi")
assert(file_exists("/tmp/d/x.txt"))
assert(is_dir("."))
let s = read_file("/tmp/d/x.txt")
let _ = remove_file("/tmp/d/x.txt")
let _ = env_set("K", "v")
let v = env_get("K")
print_int(argc())
print(arg_get(0))
let a = args()                   // []string of argv
log_info("hello")                // "[<now_ms> info] hello"
log_warn("careful")
log_error("boom")
log_kv("info", "user", "ada")
match parse_int("42") { Ok(v) => print_int(v), Err(_) => {} }
print_float(parse_float("3.5"))
print(base64_encode("hi"))
print(hex_encode("AB"))
assert_eq(abs(-3), 3)
assert(ints_contains(sort_ints([3, 1, 2]), 1))
let xs = sort_ints([3, 1, 2])
let ss = sort_strings(["c", "a", "b"])
assert(regex_match("^hi$", "hi"))
assert(regex_match("a.c", "abc"))      // `.` = any char
assert(regex_match("ab*c", "abbbc"))   // `*` = greedy star on prior atom
assert(regex_match("ab+c", "abbbc"))   // `+` = one or more
assert(regex_match("ab?c", "ac"))      // `?` = zero or one
assert(regex_match("cat|dog", "dog"))  // `|` alternation
assert(regex_match("[a-z]+", "hi"))    // character class + range
assert(regex_match("[^0-9]+", "hi"))   // negated class
assert(regex_match("(ab)+c", "ababc")) // grouping
print(regex_capture("a(b+)c", "xxabbbc", 1))  // "bbb" — group 1; 0 = full match
print(regex_find("ab", "xxabyy"))
print(regex_find("a.*c", "xxabyczz"))
let t0 = now_ms()
time_sleep_ms(1)                       // alias of sleep_ms
print_int(elapsed_ms(t0))
// exit(7)                             // process exit with status code

Regex seed supports literals, ., X*/X+/X?, |, [abc]/[a-z]/[^…], (…) groups, and ^/$. Groups compose only (no $1 extraction).

Multi-file modules (merge imports; optional as alias namespace):

// examples/import_lib.mko — flat merge
import "./import_lib.mko"
print_int(lib_add(2, 3))

// examples/import_as_main.mko — namespaced
import "./import_ns_lib.mko" as lib
print_int(lib.add(10, 32))   // calls lib__add

// Std packages (resolve under std/; auto-alias)
import "strings"
import "sync"
assert(strings.contains("hi", "h"))
let m = sync.rwmutex()

// Grouped import (preferred for multiple paths)
import (
    "strings"
    "path"
    lib "./import_ns_lib.mko"
)
assert(strings.contains("hi", "h"))
assert_eq_str(path.join_path("a", "b"), "a/b")

// Brace form also accepted
import { "fmt"; "strings" }

mako fmt sorts imports and emits a single import ( … ) block when there are two or more.

mako run prog.mko -- arg1 arg2 forwards args to the program.


15. Testing

Feature Syntax
Test file foo_test.mko (same dir as code)
Test function fn TestAdd() { … }
Run all mako test [path]
Filter mako test --run TestAdd or -r 'Test*' or -r '/^TestAdd$/'
Verbose mako test -v / --verbose (lists matched test functions)
Repeat mako test --count N
Coverage mako test --coverage
Categories fn FuzzXxx() / PropertyXxx() / SnapshotXxx() / MockXxx() / FixtureXxx()
Subtests t_run("name") · nest with t_run_nested("child")Parent/child
// examples/testing/add.mko
fn add(a: int, b: int) -> int {
    return a + b
}

// examples/testing/add_test.mko
fn TestAdd() {
    assert_eq(add(2, 3), 5)
}

fn TestAddTable() {
    let a = [1, 2, 10]
    let b = [1, 3, 5]
    let want = [2, 5, 15]
    for i in 3 {
        assert_eq(add(a[i], b[i]), want[i])
    }
}
// examples/testing/sub_test.mko
fn TestSubs() {
    t_run("ok")
    assert_eq(1, 1)
    t_run("also")
    assert_eq(2, 2)
}

fn TestNested() {
    t_run("outer")
    assert_eq(1, 1)
    t_run_nested("inner")   // prints TestNested/outer/inner
    assert_eq(2, 2)
}

Helpers: assert, assert_eq, assert_eq_str, fail("msg"). A failed assert fails the current test (or subtest) and continues to the next. Exit code is non-zero if any test failed.

cargo run --release -- test examples/testing
cargo run --release -- test examples/testing --run TestAdd
cargo run --release -- test examples/testing -r TestSubs
cargo run --release -- test examples/testing -v
cargo run --release -- test examples/testing -v -r 'TestAdd*'
cargo run --release -- test examples/testing -r '/^TestAdd$/'
cargo run --release -- test examples/testing -r '/Add|Mul/'

-run / -r matching (in order):

  1. /pattern/ — Rust regex (unanchored unless you write ^/$); invalid pattern matches nothing
  2. * / ? glob
  3. otherwise substring

-v prints run: TestA, TestB before compiling each matched file.


16. Tooling

mako check path.mko          # lex, parse, typecheck (incremental)
mako check --json path.mko   # JSON diagnostics for CI/IDE/AI tooling
mako build path.mko -o bin   # → C → .o cache → link (debug -O0; --release -O3 -flto)
mako build -j 8 --no-incremental path.mko   # parallel jobs; disable cache
mako run path.mko [-- args...]   # compile + run; trailing args → argc/args
mako test [path] [--run PAT] [-v] [--count N] [--coverage]  # tests + categories
mako fmt [paths...] [-w|-l|-d] [-p NAME]   # formatter: stdout / write / list / diff
mako lint [path] [-p NAME]            # workspace-aware typecheck + rules
mako bench [path] [-p NAME] [--json]  # workspace-aware bench_*.mko wall time
mako profile [path] [-p NAME] [--release] [--json] -- [args...]  # compile/run profile
mako doc [path]              # API markdown + runnable examples + search index
mako metadata [path]         # JSON symbol graph + AST summary
mako api diff old new        # breaking API change detector
mako init [--backend|--workspace]    # app / API service / workspace
mako pkg init|list|fetch|lock|add|remove|audit   # path first-class; git via fetch
mako deploy docker [path] --entry main.mko --bin server --port 8080
mako deploy serverless [path] --provider cloud-run|fly --name mako-app
mako deploy wasm wasm-dist --entry examples/wasi_hello.mko --wasm hello.wasm
mako deploy plugin my-plugin --name my-plugin --kind native

VS Code support under editors/vscode/ includes syntax highlighting, snippets, tasks, command palette actions, mako-native debug launch configs, and a dependency-free client for mako lsp covering diagnostics, hover, completion, definitions, references, rename, code actions, symbols, and signature help. Configure the executable path with mako.path; native debugging delegates to CodeLLDB (lldb) or Microsoft C/C++ (cppdbg) via mako.debug.adapter.

Flags of note: --time, -j / MAKO_JOBS, --no-incremental, --target <triple>, --sanitize=thread|address, --static-link, --no-static-link, --emit-c. Linux musl targets default to static linking; glibc Linux, macOS, Windows, and WASM stay dynamic/default unless static linking is explicitly supported and requested. See BUILD.md · PERFORMANCE.md · SECURITY.md.

mako deploy docker writes a multi-stage Dockerfile plus .dockerignore. Default mode builds a static x86_64-unknown-linux-musl binary and copies it into scratch; --mode debian uses debian:bookworm-slim with CA certificates for apps that need OS trust stores or shell/debug tooling. mako deploy serverless builds on that Dockerfile and writes provider starter manifests: cloudrun.service.yaml for Cloud Run or fly.toml for Fly.io. mako deploy wasm writes a browser/edge static starter around the WASI preview1 loader: index.html, mako-wasi-loader.js, build-wasm.sh, and a README that names the preview2/component boundary. mako deploy plugin writes native or WASM plugin skeletons using the ABI seed in runtime/mako_plugin.h; see ABI.md.

Security APIs (stdlib)

assert(const_eq(got, want) == 1)          // timing-safe
let s = secret_from_str(key); secret_drop(s)
assert(http_header_ok(name, val) == 1)    // reject CR/LF injection
unsafe { let v = unsafe_index(xs, i) }    // explicit bounds opt-out
// DB: sqlite_query_int / sqlite_query_int_params — parameterized only
// Crew exit cancel_joins; [package] systems = true forbids GC weakening

Session Management, Authentication & Authorization

Mako ships a complete toolkit for cookies, sessions, CSRF protection, authentication, signed tokens, and role-based access control. All security- sensitive comparisons use constant-time equality to prevent timing attacks.

Runtime: runtime/mako_security.h.

Cookies

Builtin Signature Purpose
cookie_get (header: string, name: string) -> string Parse a cookie value from a Cookie: header
cookie_make (name: string, value: string, max_age: int) -> string Create a Set-Cookie header string (HttpOnly, SameSite=Lax, Path=/)
let cookie_hdr = http_header(c, "Cookie")
let sid = cookie_get(cookie_hdr, "sid")

let set_cookie = cookie_make("sid", session_id, 86400)  // 24-hour expiry
let _ = http_respond_ct(c, 200, "application/json", body, set_cookie)

Sessions

Builtin Signature Purpose
session_id_new () -> string Generate a 32-char random hex session ID (16 bytes of cryptographic randomness)
auth_session_cookie (cookie_header: string, cookie_name: string, expected: string) -> int Constant-time check of a session cookie against expected value (1=match, 0=no)
let sid = session_id_new()           // e.g. "a3f8...c210" (32 hex chars)
cmap_set(sessions, sid, user)

// Later, on a protected route:
let cookie_hdr = http_header(c, "Cookie")
if auth_session_cookie(cookie_hdr, "sid", expected_sid) == 1 {
    // session valid
}

CSRF Protection

Builtin Signature Purpose
csrf_token () -> string Generate a random CSRF token
csrf_check (expected: string, submitted: string) -> int Constant-time comparison (1=match, 0=no)
let token = csrf_token()
// embed token in the HTML form or return it as a response header

// On form submission:
let submitted = json_get_string(body, "csrf_token")
if csrf_check(token, submitted) == 0 {
    let _ = http_respond_json(c, 403, "{\"error\":\"CSRF token mismatch\"}")
    return
}

Authentication

Builtin Signature Purpose
auth_bearer (authorization: string) -> string Extract token from "Bearer \<token>" header
auth_check_bearer (authorization: string, expected_token: string) -> int Constant-time bearer token verification
auth_basic_header (user: string, pass: string) -> string Build a "Basic \<base64>" authorization header
auth_check_basic (authorization: string, user: string, pass: string) -> int Verify Basic auth credentials
// Bearer token
let auth_hdr = http_header(c, "Authorization")
let token = auth_bearer(auth_hdr)                       // extract raw token
if auth_check_bearer(auth_hdr, expected_token) == 1 {
    // authorized
}

// Basic auth
let hdr = auth_basic_header("admin", "s3cret")          // build header
if auth_check_basic(auth_hdr, "admin", "s3cret") == 1 {
    // credentials valid
}

Signed Tokens (HMAC-SHA256)

Builtin Signature Purpose
auth_token_sign (subject: string, secret: string) -> string Sign a subject, returns "subject.hmac_signature"
auth_token_check (token: string, secret: string) -> int Verify a signed token (1=valid, 0=invalid)
auth_token_subject (token: string) -> string Extract subject from "subject.signature" token
let secret = "my_signing_key"
let token = auth_token_sign("user:42", secret)   // "user:42.abc123..."
if auth_token_check(token, secret) == 1 {
    let sub = auth_token_subject(token)           // "user:42"
}

Role-Based Access Control

Builtin Signature Purpose
auth_role_has (roles_csv: string, role: string) -> int Check if a comma-separated roles string contains a role
authz_allow_role (user_roles_csv: string, required_roles_csv: string) -> int Check if user has any of the required roles
let user_roles = "editor,viewer"
if auth_role_has(user_roles, "admin") == 0 {
    // user is not an admin
}
if authz_allow_role(user_roles, "editor,admin") == 1 {
    // user has at least one of the required roles
}

Practical Session Flow

let sessions = cmap_new()

fn handle_login(c: int) {
    let body = http_body(c)
    let user = json_get_string(body, "user")
    let pass = json_get_string(body, "pass")

    // verify credentials (your logic here)

    let sid = session_id_new()
    cmap_set(sessions, sid, user)
    let cookie = cookie_make("sid", sid, 86400)  // 24h
    let _ = http_respond_ct(c, 200, "application/json", "{\"ok\":true}", cookie)
}

fn handle_protected(c: int) {
    let cookie_hdr = http_header(c, "Cookie")
    let sid = cookie_get(cookie_hdr, "sid")
    if cmap_has(sessions, sid) == 0 {
        let _ = http_respond_json(c, 401, "{\"error\":\"unauthorized\"}")
        return
    }
    let user = cmap_get(sessions, sid)
    let _ = http_respond_json(c, 200, json_object("user", user))
}

Security properties: - All token/password comparisons use constant-time equality (prevents timing attacks) - Cookies default to HttpOnly (no JS access), SameSite=Lax (CSRF protection), Path=/ - Session IDs use cryptographic random bytes (mako_random_bytes) - Secrets can be wiped from memory with secret_from_str / secret_drop


17. Extern C

// examples/extern_c.mko — links runtime/mako_extern_demo.c
extern "C" fn mako_c_abs(n: int) -> int
extern "C" fn mako_c_add(a: int, b: int) -> int

fn main() {
    print_int(mako_c_abs(0 - 42))
    print_int(mako_c_add(20, 22))
}

Plugin ABI seed:

mako deploy plugin my-plugin --name my-plugin --kind native
mako deploy plugin my-wasm-plugin --name my-wasm-plugin --kind wasm

Native plugins use runtime/mako_plugin.h and export mako_plugin_entry. WASM plugin skeletons emit a manifest and exported function sketch. Host-side loading/capabilities remain roadmap work.


WASM / WASI (preview1 Done)

With wasi-sdk installed (WASI_SDK_PATH):

mako build examples/wasi_hello.mko --target wasm32-wasi -o out/wasi_hello.wasm
wasmtime out/wasi_hello.wasm

mako build examples/wasi_args_env.mko --target wasm32-wasi -o out/wasi_args_env.wasm
wasmtime --env MAKO_WASI_GREET=hi out/wasi_args_env.wasm hello

mkdir -p out/wasi_fs_sandbox && echo seed > out/wasi_fs_sandbox/in.txt
mako build examples/wasi_fs.mko --target wasm32-wasi -o out/wasi_fs.wasm
wasmtime --dir=out/wasi_fs_sandbox::. out/wasi_fs.wasm

wasm32-wasi normalizes to wasm32-wasip1. Builds use wasi-sdk clang + a minimal runtime (-DMAKO_WASI — print/fib/argc/arg_get/env_get/ read_file/write_file OK with --dir preopens; sockets/TLS/DB stay native-only). Pass env from the host (wasmtime --env); env_set soft-fails on WASI. If the SDK or wasmtime is missing, ./scripts/wasi-verify.sh prints skip: and exits 0. Details: WASM.md.

For browser/edge static hosting:

mako deploy wasm wasm-dist --entry examples/wasi_hello.mko --wasm hello.wasm
./wasm-dist/build-wasm.sh
python3 -m http.server -d wasm-dist 8080

Target / roadmap (not in this guide as “works”)

Already Done (see STATUS): CFG NLL, HTTP/1.1 + HTTPS + H2 TLS beachhead, gRPC/H3-client pieces, WASI preview1, operators/imports/mako version, stdlib Waves 1–9 (~98% major areas).

Still Target / Later (VISION): colored async/await, complete Unicode property database / PCRE, interoperable Huffman JPEG, live reflect field values, full SMTP AUTH-over-TLS, native WASI preview2 components / browser DOM, optional GC, SIMD/GPU, deep LSP, homebrew-core publish (external). See VISION.md and STATUS.md.

Book: The Mako Book.


Example index

Topic File
Hello examples/hello.mko
WASI hello examples/wasi_hello.mko
WASI args / env examples/wasi_args_env.mko
WASI FS preopens examples/wasi_fs.mko
Conversions examples/convert.mko, examples/testing/convert_test.mko
make / []byte("lit") examples/make_bytes.mko, examples/testing/make_bytes_test.mko
int family examples/integers.mko, examples/bytes.mko, examples/bad/int*
Slices / copy / []byte examples/slice.mko, slice64.mko, bytes.mko, testing/slice*_test.mko, bytes_test.mko
Types OK / bad examples/types_ok.mko, examples/bad/
Result / match examples/result.mko, examples/match.mko, match_int.mko, match_or.mko
Interfaces (dyn) examples/iface_method.mko, iface_self.mko, iface_dyn.mko, iface_multi.mko, iface_unit_dyn.mko
Enum methods examples/enum_method.mko
Arena []Struct examples/arena_struct.mko, arena_append.mko
path / file / env / args / log examples/path_join.mko, file_env.mko, fs_polish.mko, cli_args.mko, log_ts.mko
Hold partial moves examples/hold_partial.mko, hold_nested_partial.mko
parse / base64 / sort / regex examples/parse_num.mko, base64.mko, sort.mko, regex_seed.mko
Multi-file import examples/import_main.mko, import_as_main.mko, testing/import_mod_test.mko, import_as_test.mko, import_group_test.mko, import_brace_test.mko
Hold Copy re-read examples/hold_copy_reread.mko
exit / duration examples/exit_code.mko, testing/duration_test.mko, testing/exit_builtin_test.mko
HTTP/1.1 server examples/http_server.mko (./scripts/http-server-smoke.sh)
JSON API backend examples/api_backend/ (./scripts/api-backend-smoke.sh)
HTTP library examples/http_lib/ (./scripts/http-lib-smoke.sh) · testing/http_lib_test.mko
Systems append log examples/systems_log/
Mini KV engine examples/db_engine/ · testing/db_engine_test.mko
Microbench examples/bench/ · ./scripts/bench.sh
HTTPS server (OpenSSL) examples/https_server.mko (./scripts/https-server-smoke.sh)
HTTP/2 TLS server examples/h2_server.mko (./scripts/h2-server-smoke.sh)
HTTP client examples/http_get.mko
Crew / channels examples/concurrency.mko, examples/channels.mko
Select examples/select_default.mko, examples/select_fair.mko
Actors examples/actor.mko
HTTP / WS / TLS examples/http_*.mko, ws_*.mko, tls_*.mko
Poll / kqueue examples/io_*.mko
JSON examples/derive_json.mko, json_*.mko, json_map.mko
SQLite / Redis examples/sqlite.mko, redis_ping.mko
Tests examples/testing/
Extern examples/extern_c.mko
Edit this page on GitHub Report an issue