diff --git a/NEXT.md b/NEXT.md index 5b0d339..7842d27 100644 --- a/NEXT.md +++ b/NEXT.md @@ -429,11 +429,37 @@ run one lane at a time; item 4 is disjoint and runs alongside any of them. reference; `#_`; hex, binary and addresses on primitives in the inspector. The indentation one is worth doing first within this batch — it costs friction on every keystroke today. -5. **`Handle` and the pool.** A reference to something that can die, that reports that it died rather than silently +5. **Union values, then the macro expander, then `Result`/`try`.** Promoted above `Handle` on the author's call — + macros are the thing most worth wanting, and unions are the only thing between here and them. + + **Unions are closer than the milestone number suggests.** `Tast.arm` already carries `acase` (a case name) and + `binds` (the slots a payload binds to) — that is union shape, built and exercised, because `Option` is a two-case + union wearing a special coat and `match` over it works today. What is missing is the declared layout (a tag plus the + largest variant), construction, and letting `match` bind payloads from a user-declared union. `defunion` already + parses and its shape is already checked; `check.ml:312` and `:1075` are the two refusals to remove. + + **Then macros**, which are blocked on exactly this and nothing else: a macro is `[Form] -> Form`, so `Form` has to be + a Flan union whose *layout* the compiler and the `dlopen`ed macro agree on byte for byte. `NEXT.md`'s macro section + has the expander design — a pre-pass fixpoint before `Parse`, `gensym` as a compiler-side counter, quasiquote as a + desugaring over `Form`. The exit criterion is already written: move `when` or `cond` out of `parse.ml` into the + prelude as a `defmacro` with the existing tests unchanged and still green. + + Macros are what buy `with-drawing` and `with-mode-2d` over raylib's begin/end pairs, the hiccup DSL if a JS backend + ever happens, and the removal of special forms from the compiler. + + **`Result`/`try`** follows, being another union. + + **Generics are deliberately NOT here.** They feel adjacent and are not urgent, and today is the evidence: `Vec` and + `Map` were the obvious customer and needed none — they are type-erased, with the compiler emitting sizes and the + hash/equality pair per call site, which is Odin's design. The remaining customers are user-written allocators and + escaping closures, and both actually want **function values**, which is a separate milestone-5 feature. Leave + generics until something concrete needs them. + +6. **`Handle` and the pool.** A reference to something that can die, that reports that it died rather than silently resolving to whatever reused the slot. Wanted on its own terms for entities referred to across frames, and it is the real gate on classes. Buildable now that the allocator exists. -6. **Signature generations and stale-caller warnings.** The biggest remaining hole in "you never restart the program" — +7. **Signature generations and stale-caller warnings.** The biggest remaining hole in "you never restart the program" — a changed signature is still refused rather than versioned. Last because it is the largest and nothing else waits on it.