Status: current. The project's timeline from the first commit to today; it is extended when a line of work lands, not rewritten.
This page is the history of Dawn from its first commit to today, one line of work per entry.
It reads forward in time, in six periods, and each entry gives the date, the release that
first shipped it where there is one, and one sentence on what changed.
The authoritative account of each entry is the design document or specification section it
links to; dates are commit dates in UTC+8, and git log holds the commits behind them.
M0–M7: from nothing to self-hosting (2026-07-11 to 07-22)#
- 2026-07-11. M0 and M1: the first day brings a Kotlin compiler to JVM bytecode and a
language server, and by its end the language has ADTs with exhaustiveness checking, records,
generics, lambdas, effect variables,
?and test blocks. (Early decisions) - 2026-07-12. M2, M3 and M4 close on the same day: comptime,
use javaand the core standard library; golden diagnostics,dawn fmtand the first tutorial; modules,Map/Setand multi-file projects, accepted on a pure-Dawn JSON library that passes JSONTestSuite. The interop trio (SAM conversion, arrays passed through, the List bridge) lands alongside. (Early decisions) - 2026-07-12. M5: the project site goes up, generated by a program written in Dawn whose JVM and native builds emit identical bytes; the Playground's backend is a Dawn program too, and its editor gets live diagnostics.
- 2026-07-12 to 07-13. trait v1: single-parameter nominal typeclasses with dictionary passing,
derive Ordand the comparison operators bridged toOrd. (trait.md) - 2026-07-14 to 07-16. M6: the production backend of dawnop.com is rewritten in Dawn in thirteen steps (07-14), traffic is cut over in full (07-15) and the Python server is retired (07-16). (m6.md, m6-retro.md)
- 2026-07-16.
Bytesbecomes a first-class type, retiring the Latin-1 string workarounds the backend rewrite had exposed. (bytes-design.md) - 2026-07-17, v0.1.0. The first tagged release; tagging now publishes the compiler jar.
dawn.tomlwith[java-deps]ships in it, replacing hand-copied classpaths. - 2026-07-18 to 07-22, v0.2.1. Pure FFI:
unsafe_purelets one host call back a pure function, and builtins move out of the compiler's table into std; the migration closes on 07-22. (pure-ffi-design.md) - 2026-07-21, v0.3.0.
MapandSetbecome persistent hash tries, ending the quadratic cost of copy-on-write. - 2026-07-22, v0.6.0. M7: the compiler written in Dawn reaches its fixed point (stage 2 and stage 3 are byte-identical), and the Kotlin compiler is frozen as the root of the bootstrap chain. (bootstrap.md)
- 2026-07-22, v0.7.0 and v0.8.0. Packages v1:
[deps]source packages, then url + hash dependencies resolved by minimal version selection, anddawn add. (package-design.md)
One compiler left (2026-07-23 to 07-31)#
- 2026-07-23, v0.8.0. M8: the first release built by the self-hosted compiler becomes the
seed, the Kotlin implementation is archived at the
kotlin-finaltag, and from here on every release is the seed of the next. (m8-selfhost-only.md, bootstrap.md) - 2026-07-25, v0.12.0. Core IR: the typed tree is lowered onto a small shared IR, and a C backend starts from it. (native-backend-plan.md)
- 2026-07-26, v0.15.0. trait v2:
==asks for anEqbound, and impls may be conditional. (trait-v2-design.md) - 2026-07-27, v0.25.0 and v0.26.0. Collections leave Java:
MapandSetarestd/hamtandListisstd/pvec, both written in Dawn, and the runtime keeps no collection classes. (collections-dejava-research.md) - 2026-07-29, v0.31.0. Perceus reference counting for the C backend: ownership inference,
dup/drop, in-place reuse, and strings brought into the account, which takes the compiler front end's peak memory on one input from 1.46 GB to 81 MB. (perceus-design.md) - 2026-07-30, v0.31.0. The C backend self-hosts: the native compiler reaches its own fixed point, B == C. (native-backend-plan.md)
Effects and the frontend (August)#
- 2026-08-01, v0.44.0. Named effects: users declare
effects and handle them withwith handle, starting with tail-resumptive handlers. (effects-design.md, spec.en.md §6) - 2026-08-02, v0.45.0 to v0.47.0. Associated types,
Iteras a prelude trait behindfor..in, and[]resolved through anIndextrait. (assoc-types-design.md, operator-traits-design.md) - 2026-08-03, v0.50.0. Two lines on the backends: the JVM side shrinks its trusted base
until
dawn/toolleaves the jar, and the native driver is completed and its backend contract written down. (jvm-base-plan.md, native-driver-plan.md) - 2026-08-04, v0.50.0.
dawnc, the native compiler, is published as a release asset. (bootstrap.md) - 2026-08-05 to 08-07, v0.52.0 to v0.58.0. The site goes bilingual (English at
/, Chinese at/zh/); the tutorial's English becomes the original, its recorded outputs are checked, and the specification and design notes get English translations. - 2026-08-06, v0.57.0.
Charbecomes an opaque type overInt. (nominal-types-design.md) - 2026-08-08, v0.61.0. Tail blocks, named arguments and default parameters, the syntax a declarative UI language will need. (tail-block-design.md, named-args-design.md)
- 2026-08-08. A second whole-repository audit, frozen against v0.60.0. (codebase-audit-v2.md)
- 2026-08-19 to 08-20, v0.67.0. Effect parameters, settled as associated effects on traits. (effect-params-design.md)
- 2026-08-20. The VS Code extension is published on the marketplace (0.1.2 on 10-01).
- 2026-08-20, v0.68.0. A wasm32-wasi target (
dawnc build --target wasm) with its own failure runtime. - 2026-08-20 to 08-28. The Elm architecture in Dawn:
packages/tea(08-20), split into a core and a terminal half (08-22);packages/tea-domover a wasm reactor (08-26); and the browser demo at/tea.html(08-28, v0.70.0). (dom-bridge-design.md) - 2026-08-21 to 08-24, v0.68.0. Effect evidence is passed from the call site, and section 6 of the specification is rewritten to match. (spec.en.md §6)
- 2026-08-27 to 08-30, v0.69.0 to v0.71.0. Native memory, second round: borrowed parameters inferred over the whole program (08-27), small objects from size-class slabs (08-28), and slabs materialized 32 KiB at a time (08-30). (perceus-design.md, slab-residency-design.md)
- 2026-08-29 to 08-30, v0.70.0. Handler-local state: a
vardeclared in a handler, which may not escape it. (handler-state-design.md) - 2026-08-30, v0.71.0. The Playground gets a real language server: each browser buffer talks to its own isolated native LSP process. (playground-lsp-design.md)
- 2026-08-31 to 09-01, v0.71.0. One-shot resumption:
ctleffects,resume kanddiscard, on both backends. (oneshot-design.md)
Devices and the standard library (2026-09-01 to 09-07)#
- 2026-09-01, v0.71.0. Every release carries a snapshot of the public API and a classified diff against the previous one.
- 2026-09-02 to 09-04, v0.71.0 to v0.76.0. The standard library's effects are split by
what they touch:
Fs(09-02),ProcandEnv(09-03),ExitandConsole(09-04); the native compiler itself runs under the five real handlers. - 2026-09-02, v0.72.0. A device backend for NVIDIA GPUs through cuTile: the
Gpueffect with a fake device,packages/tileir, andvaddend to end. (tile-backend-design.md) - 2026-09-03 to 09-07, v0.73.0 to v0.77.0. A ledger of leetgpu problems and the campaign to cover it, the view family, and a second ledger on sm_100. (tile-backend-design.md)
- 2026-09-04 to 09-07, v0.76.0 to v0.77.0. Programs stop carrying what they do not
reach: std is pruned per program (09-04), the control runtime too (09-05), and with
std/pvecpruned as well a hello-world's C drops from 1,205 lines to 438 (09-07). (std-pruning-design.md, control-freight-design.md) - 2026-09-07, v0.77.0.
teagets commands:updatereturns(model, Cmd).
Tightening (2026-09-08 to 09-30)#
- 2026-09-08 to 09-27. An incremental semantic engine is built behind an opt-in
(first phase 09-08, declaration identity 09-13), measured three times against its goal,
and its opt-in slice removed on 09-27 (tag
incremental-slice-final); the identity and scheduling it left behind stay. (incremental-semantics-removal.md, incremental-semantics-design.md) - 2026-09-23 to 09-26, v0.78.0 to v0.79.0. Gates outside GitHub: the full gate set runs
locally or on an external runner, its evidence is signed into
refs/notes/gates, releases accept it (09-24), and pull requests carrying it skip the hosted gates (09-26). (gates-external-design.md) - 2026-09-24 to 09-25, v0.78.0. The rulings of 09-24 land together:
pub(pkg); a syntax window (five keywords made contextual,$nameinterpolation removed, a leading|on or-patterns); an effects window (iois the only ambient effect,unsafe_puredeleted); unused imports are errors; builtin type privileges; gate drift guards. (package-visibility-design.md, syntax-window-design.md, effects-window-design.md, unused-imports-design.md, builtin-privileges-design.md, gate-drift-guards-design.md) - 2026-09-25 to 09-26, v0.79.0. A ratchet on gate cost: a cap on the total gate time per push, raised only by a declaration in the commit. (gate-drift-guards-design.md)
- 2026-09-25 to 09-30, v0.79.0.
packages/webtakes its fifth major version, which narrows its public surface. (web5-design.md) - 2026-09-26 to 09-27, v0.79.0. Symbol IDs: top-level functions are identified by their declaration path in the dependency graph, scheduling, header products and the LSP. (symbol-id-design.md)
- 2026-09-28 to 09-30, v0.79.0 to v0.80.0. The LSP remembers each module's check step; the median sync on the compiler's own workspace falls from 1.5–2.0 s to 0.05–0.39 s, and reuse is then keyed on what a module actually imported. (lsp-module-memo-design.md)
October#
- 2026-10-01, v0.80.0. Standard library parameter names are frozen behind a
Param-Changedeclaration. (stdlib-naming.md) - 2026-10-01, v0.80.0 to v0.81.0. Symbolic links, in three steps:
std/memfsas an in-memoryFshandler,Fs.real_path, and the compiler's tests moved onto it; on main after v0.81.0, package, module and workspace identity resolve through links. (fs-real-path-design.md) - 2026-10-01, v0.81.0.
web5.1 gives routes a typed body ceiling checked before the body is read; 5.2 follows on main. (web5-design.md) - 2026-10-01. The site is audited and fixed in three batches: the tutorial starts from a release download, the Playground ships minified and keeps edits, and the site and Playground deploy from release tags.
- 2026-10-01. The GPU reference implementations leave
std/gpuforpackages/tileref(on main, not yet released). (tile-backend-design.md) - 2026-10-06.
+ - * / %and unary-reach types of the program's own through six prelude traits,AddtoNeg, each with an effect member a device type can bind; Int and Float keep their native operators, and an opaque type does not inherit its target's arithmetic. The six names are now taken for atraitor aneffect(on main, not yet released). (arith-operator-traits-design.md) - 2026-10-06. Numeric literals take their type from what is expected:
let f: Float = 1and3.14159 * 2 * rcompile, and a type of the program's own receives literals throughFromIntandFromFloat, whose pure impls run at compile time, solet b: U8 = 300is a compile error whose range the library states (on main, not yet released). (literal-system-design.md) - 2026-10-06. A
forover a type that implementsStagedIterhands its body to a library as a closure, and each outervarthe body mentions travels through a cell the library chooses throughStagedVar, opened in declaration order. This is what lets a recorded device loop be written as a plainforwith plainvars.StagedIterandStagedVarare now taken for atraitor aneffect(on main, not yet released). (staged-for-design.md) - 2026-10-06.
std/narrow's bfloat16, binary16 and binary32 take the operators and float literals:a + bon aBF16is its correctly rounded sum,a % bthe exact remainder, andlet w: BF16 = 0.1isbf16(0.1), folded at compile time. The named functions stay (on main, not yet released). (arith-operator-traits-design.md) - 2026-10-06. std gains fixed-width integers,
I8toI32andU8toU64, one module each: opaque types overIntwhose arithmetic wraps asInt's does, whose literals are range-checked at compile time, and whose bitwise operations are named functions. The compiler still owns onlyIntandFloat; sha256 overU32measured within 1% of the masked-Intform (on main, not yet released). (literal-system-design.md)
From v0.1.0 on 2026-07-17 to v0.81.0 on 2026-10-01 there have been 83 release tags.
Decisions that were reversed#
The early decisions are kept as they were written. Where one has since been overturned, this table says what replaced it and when.
| Then | Now | When |
|---|---|---|
| The compiler is written in Kotlin, on a budget of 6–8 thousand lines (§1, D7) | The only compiler is the self-hosted one in selfhost/; the Kotlin implementation survives at the kotlin-final tag | 2026-07-23 |
| The everyday toolchain (run, test, fmt, doc, LSP) stays on the Kotlin version (M7) | Every tool comes from the self-hosted compiler | 2026-07-23 |
| The Kotlin compiler stays frozen as the bootstrap seed, like Go's go1.4 (M7) | The seed is the previous release's dawn-selfhost.jar; v0.6.0 remains the root of the replayable chain | 2026-07-23 |
| The only backend is JVM bytecode; native comes from GraalVM native-image (§1, D1) | A C backend is a self-hosting peer of the JVM backend, and a cuTile backend targets GPUs | 2026-07-30; 2026-09-02 |
| No intermediate IR (D6) | Core IR sits between checking and both backends | 2026-07-25 |
| The JVM's GC is our GC (non-goals) | The native backend has no GC; memory is managed by Perceus reference counting | 2026-07-29 |
| The effect system has two levels, pure and io (D2) | Users declare named effects and handle them; io is the only ambient effect | 2026-08-01; 2026-09-24 |
| Purity and effect marking credited to Flix, "simplified to two levels" (§4) | Named effects with handlers, control arms and handler state; the precedents surveyed are Koka and Effekt | 2026-08-01 |
| Continuation capture conflicts with the C backend's single-stack model (non-goals) | One-shot resumption (ctl, resume k, discard) works on both backends; only multi-shot stays out | 2026-08-31 to 09-01 |
| The unsafe escape hatch is not open to user code (D5) | unsafe_pure was opened to users, restricted to std, then deleted with its keyword | 2026-07-18; 2026-07-30; 2026-09-24 |
TList is a java.util.List at runtime, so the bridge costs one call (D8) | List is std/pvec, written in Dawn; a List handed to Java crosses as an Array | 2026-07-27 |
Single-parameter traits, no conditional impls; == stays structural (D9, trait v1) | Conditional impls, associated types, and == through an Eq bound | 2026-07-26; 2026-08-02 |
Map/Set are LinkedHashMap/LinkedHashSet with copy-on-write (M4) | Persistent hash tries, written in Dawn since 07-27 | 2026-07-21; 2026-07-27 |
No dawn.toml; the directory layout is the project (M4) | dawn.toml is optional and carries the project's identity and dependencies | 2026-07-17; 2026-07-22 |
A character literal is an Int (M4) | 'a' has type Char, an opaque type over Int | 2026-08-06 |
| The tutorial is eleven chapters, checked by a Kotlin test (M3) | Seventeen chapters, English original, every dawn run block run by doc-check.py | 2026-08-05 to 08-07 |
The exception barrier is java_try (M6) | It is catch_fault | 2026-07-29 |
| M5 is a plan; M6 awaits its production cutover | M5 went live on 2026-07-12; M6 cut over on 2026-07-15 and retired Python on 2026-07-16 | 2026-07-12; 2026-07-16 |
Early decisions#
Early design decisions (M0–M7) keeps the reasoning behind each choice made before self-hosting, as it was written at the time.