Every language surface and every part of the toolchain the catalogue tracks, in one list. Each entry has a page of its own in doc/features/ in the repository, where @F2 is F2.md.
The two halves read differently. An @F page says what the feature is and how it aids you, and 77 of the 91 carry a runnable example; the rest name what demonstrates them instead, because a loft program cannot run the compiler that runs it. An @I page says what the part does and where it lives in the source — it describes how loft is built, not something you write.
The catalogue is generated from the loft-lang/features issue tracker, which is the single source of truth: every entry is an issue, and make features-check regenerates this page and fails on any difference. A feature you can name and cannot find below is missing from the TRACKER — that is a gap in the catalogue rather than a gap in loft, and the chapters of this reference are the wider list.
Language features
- @F1 — Nullable value semantics — in-band sentinels + null-fallback arithmetic
- @F2 —
??null-coalescing operator (incl.?? return) - @F3 — Primitive scalar types (integer, float, single, boolean, character)
- @F4 — Ranged/width integer types (u8/i8/u16/i16/i32/u32)
- @F5 — Type conversions — implicit, format-only, and explicit
as - @F6 —
vector<T>— append, index, slice, comprehensions, aggregates, map/filter/reduce - @F7 —
hash<T[keys]>keyed collection - @F8 —
sorted<T[keys]>collection - @F9 —
index<T[keys]>B-tree index (asc/desc, multi-key) - @F10 —
iterator<T>values - @F11 — Tuples — anonymous fixed-arity
(T1, T2, …) - @F12 — Struct records — fields,
= default,computed,limit/not null/assert - @F13 — Simple enums (ordered value types)
- @F14 — Polymorphic struct-enums (per-variant fields)
- @F15 — Enum-scoped variant names + context inference
- @F16 — Functions & declarations (
pub, parameters, return) - @F17 — Named arguments + default parameter values
- @F18 —
constparameters - @F19 — Method dispatch via
self/both - @F20 — Variant-based dynamic dispatch
- @F21 — References
&T— parameters + write-back bindings - @F22 — Closures & lambdas (value capture, cross-scope)
- @F23 — Function references as first-class values
- @F24 — Higher-order functions (map / filter / reduce)
- @F25 — Generics — type variables
<T>,<K, V>, inferred; generic structs - @F26 — Interfaces & bounded generics (
<T: A + B>, operator interfaces) - @F27 —
if/elseas an expression - @F28 —
for-in loops — ranges, loop attributes, filtered,rev() - @F29 — Pattern matching — enum/scalar/tuple, guards, or-patterns, exhaustiveness
- @F30 —
isvariant check (+ field capture) - @F31 —
break/continue+ labelled forms - @F32 — Custom iterators via
operator next(self) -> T? - @F33 —
par(...)parallel for-loop - @F34 — Coroutines / generators —
yield,yield from - @F35 — String literals —
{expr}interpolation + backtick multiline - @F36 — String formatting / format specifiers (+ for-expressions)
- @F37 — Operator set — arithmetic/comparison/logical/bitwise/unary,
** - @F38 — Arithmetic safety — integer overflow/÷0 → null; null propagates through arithmetic
- @F39 — Math & trigonometry library
- @F40 — File & directory I/O (+ durable-store binding)
- @F41 — Environment & arguments (env vars, arguments(), program dirs, path resolution)
- @F42 — JSON — json_parse, JsonValue, Type.parse, to_json
- @F43 — Random numbers (rand_seed / rand / rand_indices)
- @F44 — Logging & diagnostics API (log_*, print, assert, panic)
- @F45 —
sizeof() - @F46 — Type aliases (
type X = …) - @F47 — Library imports / module system (
useforms,pub) - @F48 — The
loftCLI — run a program,--interpret/--native,--timeout,--help - @F49 — REPL — interactive sessions
- @F50 — Introspection —
loft introspect(bytecode / native Rust / slot tables) - @F51 — Debugger — breakpoints, frame capture, scripted RPC
- @F52 — Source formatter — canonical
.loftoutput - @F53 — Native-binary backend (
--native→ rustc) - @F54 — Browser / WASM target (
--html/--native-wasm) - @F55 — Package management (
loft install,loft.toml, lockfile) - @F56 — Live code reload — patch a running program
- @F88 — Stack traces (stack_trace)
- @F89 — Test runner (fn test_*, loft --tests / loft test)
- @F92 — Direct C binding —
#c "symbol" "signature", no rustc and no glue crate - @F93 — Paged & remote store loading — read part of a dataset over HTTP range
- @F94 — Type-directed interpolation — a type receives the literal/hole boundary
- @F95 — Value structs (
value struct) — copy semantics, stored inline - @F96 —
x?default-fallback operator — discharge a nullable to its type default - @F97 —
lenvssize— logical count vs bytes occupied - @F98 —
spatial<T[x,y]>— position-keyed collection for proximity queries - @F99 — Sequence match patterns — alternation, optionals, repetition, capture
- @F100 — Dead-code lint — a local never read, and a write whose value is lost
- @F101 — The build phase —
loft build, declared targets, zero-config defaults - @F102 — Android target —
--native-android, APK packaging, GL surface and touch input - @F103 —
deliver/expose— hand a loft value to JavaScript with no copy - @F104 —
store_reclaim()— give a store's unused file space back - @F105 — Custom
to_textformat hook — a type owns how it prints - @F106 — Copy and move semantics — when two names share data, and when they do not
- @F107 — Type reflection — the declared shape of a type, as data
- @F108 — Lazy store binding — a collection fetches on a miss
- @F109 —
#superseded— steer callers to a newer form without breaking the old one - @F110 — Diagnostic suggestions — what to write instead, checked by running it
- @F111 —
for f in s#fields— a compile-time loop over a struct's scalar fields - @F112 —
store_release()— say a record is finished, and stop holding it in memory - @F113 — Associated types — an interface names a companion type
- @F114 — A library type reads an element through a named method —
[…]is the built-in collections' - @F115 —
OpDrop— a type runs code when its scope lets it die - @F118 — Time (now / ticks)
- @F119 — Store locks (#lock)
- @F120 — Lexer in loft (lib/lexer.loft) — part of the loft-in-loft front end, not a user library yet
- @F121 — Parser in loft (lib/parser.loft) — part of the loft-in-loft front end, not a user library yet
- @F122 — Multiple dispatch — one name, a definition per combination of parameter types
- @F123 — Foreign stores — a mapped file or a library's buffer read in place, a slice of it a view
- @F124 — Operators on a program's own type —
operator compare,plus,minus,times,negate,divided_by,remainder,to_<type> - @F125 — Text slicing —
s[a..b],s[a..],s[..b],s[i](byte offsets;char_slicefor characters) - @F126 — A store's failure arm —
place = value else { … }runs when the write did not land
Tooling and infrastructure
- @I57 — Lexer
- @I58 — Parser (two-pass recursive descent)
- @I59 — Type resolver
- @I60 — Scope & dependency/lifetime tracker (deps)
- @I61 — Stack slot allocator
- @I62 — IR data model (Value/Type/Data)
- @I63 — Store-resident IR (reader + handle + materializer)
- @I64 — Bytecode compiler (IR -> bytecode)
- @I65 — Bytecode code generator
- @I66 — Bytecode VM / executor
- @I67 — Opcode implementations
- @I68 — Native Rust generator
- @I69 — Word-addressed store
- @I70 — Database — alloc / persistence / journal / snapshot / schema
- @I71 — DbRef pointers & collection keys
- @I72 — Parallel execution runtime
- @I73 — Native function registry
- @I74 — CDylib extension loader
- @I75 — Diagnostics collector
- @I76 — Logger runtime
- @I77 — Registry / manifest / lockfile resolution
- @I78 — Live-reload dispatch
- @I79 — Documentation generator (maintainer tooling)
- @I80 — Tracker indexer (maintainer tooling)
- @I81 — Feature-catalogue sync generator (issues → in-project mirror + example tests)
- @I82 — Sandbox policy & enforcement
- @I83 — Dev server (--serve / --rpc)
- @I84 — Coroutine runtime / yield codec
- @I85 — Engine-host kernel natives
- @I86 — Startup cache & embedded stdlib
- @I87 — Auto-use / lazy library triggers
- @I90 — Shared utilities & data structures
- @I91 — Editor tooling: language server (LSP), debug adapter (DAP), resolution index
- @I116 — Library placement — in-process, a worker, or another machine
- @I117 — Git query natives — a repository as a typed library, not a subprocess
fn main() {
println("the feature catalogue is generated from the issue tracker");
}
Run it yourself
This page is a loft program. It runs here, in your browser — press Run, then ask it something.
Stop on a line
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// GENERATED by tools/features/gen.loft — DO NOT EDIT.
// @NAME: Feature catalogue
// @TITLE: What each catalogued language and tooling feature is for.
//
// Every language surface and every part of the toolchain the catalogue tracks,
// in one list. Each entry has a page of its own in `doc/features/` in the
// repository, where `@F2` is `F2.md`.
//
// The two halves read differently. An `@F` page says what the feature is and
// how it aids you, and 77 of the 91 carry a runnable example; the rest
// name what demonstrates them instead, because a loft program cannot run the
// compiler that runs it. An `@I` page says what the part does and where it lives
// in the source — it describes how loft is built, not something you write.
//
// The catalogue is generated from the `loft-lang/features` issue tracker, which is
// the single source of truth: every entry is an issue, and `make features-check`
// regenerates this page and fails on any difference. A feature you can name and
// cannot find below is missing from the TRACKER — that is a gap in the catalogue
// rather than a gap in loft, and the chapters of this reference are the wider list.
//
// ## Language features
//
// - **@F1** — Nullable value semantics — in-band sentinels + null-fallback arithmetic
// - **@F2** — `??` null-coalescing operator (incl. `?? return`)
// - **@F3** — Primitive scalar types (integer, float, single, boolean, character)
// - **@F4** — Ranged/width integer types (u8/i8/u16/i16/i32/u32)
// - **@F5** — Type conversions — implicit, format-only, and explicit `as`
// - **@F6** — `vector<T>` — append, index, slice, comprehensions, aggregates, map/filter/reduce
// - **@F7** — `hash<T[keys]>` keyed collection
// - **@F8** — `sorted<T[keys]>` collection
// - **@F9** — `index<T[keys]>` B-tree index (asc/desc, multi-key)
// - **@F10** — `iterator<T>` values
// - **@F11** — Tuples — anonymous fixed-arity `(T1, T2, …)`
// - **@F12** — Struct records — fields, `= default`, `computed`, `limit`/`not null`/`assert`
// - **@F13** — Simple enums (ordered value types)
// - **@F14** — Polymorphic struct-enums (per-variant fields)
// - **@F15** — Enum-scoped variant names + context inference
// - **@F16** — Functions & declarations (`pub`, parameters, return)
// - **@F17** — Named arguments + default parameter values
// - **@F18** — `const` parameters
// - **@F19** — Method dispatch via `self` / `both`
// - **@F20** — Variant-based dynamic dispatch
// - **@F21** — References `&T` — parameters + write-back bindings
// - **@F22** — Closures & lambdas (value capture, cross-scope)
// - **@F23** — Function references as first-class values
// - **@F24** — Higher-order functions (map / filter / reduce)
// - **@F25** — Generics — type variables `<T>`, `<K, V>`, inferred; generic structs
// - **@F26** — Interfaces & bounded generics (`<T: A + B>`, operator interfaces)
// - **@F27** — `if` / `else` as an expression
// - **@F28** — `for`-in loops — ranges, loop attributes, filtered, `rev()`
// - **@F29** — Pattern matching — enum/scalar/tuple, guards, or-patterns, exhaustiveness
// - **@F30** — `is` variant check (+ field capture)
// - **@F31** — `break` / `continue` + labelled forms
// - **@F32** — Custom iterators via `operator next(self) -> T?`
// - **@F33** — `par(...)` parallel for-loop
// - **@F34** — Coroutines / generators — `yield`, `yield from`
// - **@F35** — String literals — `{expr}` interpolation + backtick multiline
// - **@F36** — String formatting / format specifiers (+ for-expressions)
// - **@F37** — Operator set — arithmetic/comparison/logical/bitwise/unary, `**`
// - **@F38** — Arithmetic safety — integer overflow/÷0 → null; null propagates through arithmetic
// - **@F39** — Math & trigonometry library
// - **@F40** — File & directory I/O (+ durable-store binding)
// - **@F41** — Environment & arguments (env vars, arguments(), program dirs, path resolution)
// - **@F42** — JSON — json_parse, JsonValue, Type.parse, to_json
// - **@F43** — Random numbers (rand_seed / rand / rand_indices)
// - **@F44** — Logging & diagnostics API (log_*, print, assert, panic)
// - **@F45** — `sizeof()`
// - **@F46** — Type aliases (`type X = …`)
// - **@F47** — Library imports / module system (`use` forms, `pub`)
// - **@F48** — The `loft` CLI — run a program, `--interpret` / `--native`, `--timeout`, `--help`
// - **@F49** — REPL — interactive sessions
// - **@F50** — Introspection — `loft introspect` (bytecode / native Rust / slot tables)
// - **@F51** — Debugger — breakpoints, frame capture, scripted RPC
// - **@F52** — Source formatter — canonical `.loft` output
// - **@F53** — Native-binary backend (`--native` → rustc)
// - **@F54** — Browser / WASM target (`--html` / `--native-wasm`)
// - **@F55** — Package management (`loft install`, `loft.toml`, lockfile)
// - **@F56** — Live code reload — patch a running program
// - **@F88** — Stack traces (stack_trace)
// - **@F89** — Test runner (fn test_*, loft --tests / loft test)
// - **@F92** — Direct C binding — `#c "symbol" "signature"`, no rustc and no glue crate
// - **@F93** — Paged & remote store loading — read part of a dataset over HTTP range
// - **@F94** — Type-directed interpolation — a type receives the literal/hole boundary
// - **@F95** — Value structs (`value struct`) — copy semantics, stored inline
// - **@F96** — `x?` default-fallback operator — discharge a nullable to its type default
// - **@F97** — `len` vs `size` — logical count vs bytes occupied
// - **@F98** — `spatial<T[x,y]>` — position-keyed collection for proximity queries
// - **@F99** — Sequence match patterns — alternation, optionals, repetition, capture
// - **@F100** — Dead-code lint — a local never read, and a write whose value is lost
// - **@F101** — The build phase — `loft build`, declared targets, zero-config defaults
// - **@F102** — Android target — `--native-android`, APK packaging, GL surface and touch input
// - **@F103** — `deliver` / `expose` — hand a loft value to JavaScript with no copy
// - **@F104** — `store_reclaim()` — give a store's unused file space back
// - **@F105** — Custom `to_text` format hook — a type owns how it prints
// - **@F106** — Copy and move semantics — when two names share data, and when they do not
// - **@F107** — Type reflection — the declared shape of a type, as data
// - **@F108** — Lazy store binding — a collection fetches on a miss
// - **@F109** — `#superseded` — steer callers to a newer form without breaking the old one
// - **@F110** — Diagnostic suggestions — what to write instead, checked by running it
// - **@F111** — `for f in s#fields` — a compile-time loop over a struct's scalar fields
// - **@F112** — `store_release()` — say a record is finished, and stop holding it in memory
// - **@F113** — Associated types — an interface names a companion type
// - **@F114** — A library type reads an element through a named method — `[…]` is the built-in collections'
// - **@F115** — `OpDrop` — a type runs code when its scope lets it die
// - **@F118** — Time (now / ticks)
// - **@F119** — Store locks (#lock)
// - **@F120** — Lexer in loft (lib/lexer.loft) — part of the loft-in-loft front end, not a user library yet
// - **@F121** — Parser in loft (lib/parser.loft) — part of the loft-in-loft front end, not a user library yet
// - **@F122** — Multiple dispatch — one name, a definition per combination of parameter types
// - **@F123** — Foreign stores — a mapped file or a library's buffer read in place, a slice of it a view
// - **@F124** — Operators on a program's own type — `operator compare`, `plus`, `minus`, `times`, `negate`, `divided_by`, `remainder`, `to_<type>`
// - **@F125** — Text slicing — `s[a..b]`, `s[a..]`, `s[..b]`, `s[i]` (byte offsets; `char_slice` for characters)
// - **@F126** — A store's failure arm — `place = value else { … }` runs when the write did not land
//
// ## Tooling and infrastructure
//
// - **@I57** — Lexer
// - **@I58** — Parser (two-pass recursive descent)
// - **@I59** — Type resolver
// - **@I60** — Scope & dependency/lifetime tracker (deps)
// - **@I61** — Stack slot allocator
// - **@I62** — IR data model (Value/Type/Data)
// - **@I63** — Store-resident IR (reader + handle + materializer)
// - **@I64** — Bytecode compiler (IR -> bytecode)
// - **@I65** — Bytecode code generator
// - **@I66** — Bytecode VM / executor
// - **@I67** — Opcode implementations
// - **@I68** — Native Rust generator
// - **@I69** — Word-addressed store
// - **@I70** — Database — alloc / persistence / journal / snapshot / schema
// - **@I71** — DbRef pointers & collection keys
// - **@I72** — Parallel execution runtime
// - **@I73** — Native function registry
// - **@I74** — CDylib extension loader
// - **@I75** — Diagnostics collector
// - **@I76** — Logger runtime
// - **@I77** — Registry / manifest / lockfile resolution
// - **@I78** — Live-reload dispatch
// - **@I79** — Documentation generator (maintainer tooling)
// - **@I80** — Tracker indexer (maintainer tooling)
// - **@I81** — Feature-catalogue sync generator (issues → in-project mirror + example tests)
// - **@I82** — Sandbox policy & enforcement
// - **@I83** — Dev server (--serve / --rpc)
// - **@I84** — Coroutine runtime / yield codec
// - **@I85** — Engine-host kernel natives
// - **@I86** — Startup cache & embedded stdlib
// - **@I87** — Auto-use / lazy library triggers
// - **@I90** — Shared utilities & data structures
// - **@I91** — Editor tooling: language server (LSP), debug adapter (DAP), resolution index
// - **@I116** — Library placement — in-process, a worker, or another machine
// - **@I117** — Git query natives — a repository as a typed library, not a subprocess
fn main() {
println("the feature catalogue is generated from the issue tracker");
}