docs+rename: erase the reify name everywhere — stream is METATYPE
The compiler concept is declare/define (comptime type construction); the old "reify" framing is gone from the entire repo. - Rename: PLAN-REIFY → PLAN-METATYPE, CHECKPOINT-REIFY → CHECKPOINT-METATYPE, PLAN-POST-REIFY → PLAN-POST-METATYPE (both rewritten around declare/define); examples 0614/0615/0617 → comptime-metatype-* (+ their expected/ triplets), headers rewritten. - Scrub reify from design/execution-evolution-roadmap.md (§7 step 3 contracts, §8.1, §9 decisions, §10 gates) → declare/define / comptime type construction. - core.sx prelude pointer + parser.test.zig surface lock updated to the declare/define builtins (define(handle, info) -> Type; EnumInfo.name). No behavior change; renamed examples match their renamed snapshots. Full suite green (673), all unit tests pass. Zero `reify` tokens remain in src/docs/sx/examples.
This commit is contained in:
75
current/CHECKPOINT-METATYPE.md
Normal file
75
current/CHECKPOINT-METATYPE.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# CHECKPOINT-METATYPE — comptime type metaprogramming (`declare` / `define`)
|
||||
|
||||
Companion to [PLAN-METATYPE.md](PLAN-METATYPE.md). Update after every step (one
|
||||
step at a time, per the cadence rule).
|
||||
|
||||
## Last completed step
|
||||
**The `declare`/`define` floor — the compiler's only type-construction surface.**
|
||||
Two comptime `#builtin`s mint types; every constructor (`RecvResult`, `TryResult`,
|
||||
the one-shot form) is plain sx built over them. The compiler has ZERO knowledge of
|
||||
any named constructor.
|
||||
|
||||
- `declare() -> Type` mints an empty (undefined) nominal slot; `define(handle,
|
||||
info) -> Type` decodes the `TypeInfo` value (variant names + payload Type-tags),
|
||||
names the slot from `EnumInfo.name`, completes it byte-identical to a source
|
||||
enum, and returns the handle (so the one-shot form chains:
|
||||
`T :: define(declare(), info)`). Interp executes both against a `mint` TypeTable
|
||||
handle (`setMintTable`); `defineEnum` + `decodeVariantElements` in `interp.zig`.
|
||||
- A `::` binding or type-fn body that calls a `Type`-returning fn is
|
||||
**comptime-evaluated** (`evalComptimeType`), running the `declare`/`define`
|
||||
builtins to mint the type — no constructor-name pattern-matching. `decl.zig`
|
||||
trigger = `fnReturnsTypeValue`; type-fn trigger = `returnExprMintsType`
|
||||
(return is a `define(…)` call or a bodied `-> Type` helper).
|
||||
- Nominal identity rides the type-fn instantiation cache (`renameNominalType`
|
||||
re-keys the minted type to the mangled name); `RecvResult(i64)` at two sites is
|
||||
ONE type.
|
||||
- The type NAME travels in `EnumInfo.name` — the compiler derives no name from a
|
||||
binding LHS.
|
||||
|
||||
Examples green on the floor: `0614` (one-shot `define(declare(), …)`), `0615`
|
||||
(type-fn identity), `0617` (channel result types). `field_type` reflection still
|
||||
green (`0616`). Full suite green (673 examples).
|
||||
|
||||
## Current state
|
||||
- `modules/std/meta.sx`: `EnumVariant` / `EnumInfo{ name, variants }` / `TypeInfo`
|
||||
data types; `declare` / `define` / `type_info` / `field_type` `#builtin`s;
|
||||
`RecvResult($T)` / `TryResult($T)` sx constructors over `define(declare(), …)`.
|
||||
- Compiler primitives only: `declare`/`define` (construction), `field_type`
|
||||
(reflection). No constructor-name knowledge anywhere in the compiler — every
|
||||
named constructor is sx.
|
||||
- `type_info` still bails loudly (`call.zig:tryLowerReflectionCall`) — pending.
|
||||
|
||||
## Decision (kept)
|
||||
**Meta lives in `modules/std/meta.sx`, not the prelude.** Declaring its data types
|
||||
in the always-loaded prelude interns them into every module's type table and
|
||||
shifts every `.ir` snapshot. On-demand import keeps the prelude clean.
|
||||
|
||||
## Next step
|
||||
**Self-reference (recursive / mutually-recursive enums).** The two-statement form
|
||||
`List :: declare(); define(List, .enum(.{ … payload = *List … }))`: `declare`
|
||||
binds the handle, `define` completes it, and `*List` resolves because a pointer to
|
||||
an undefined slot is legal. Needs the top-level `define(…)` statement form to run
|
||||
at comptime in the window before any use of the type's layout (a bare top-level
|
||||
call doesn't parse today — decide the surface). Pairs with a `make_enum(variants:
|
||||
[]EnumVariant)` sx helper (a computed, non-literal variant list — exercises the
|
||||
interpreter decoding a value-arg slice).
|
||||
|
||||
Then: **`type_info($T) -> TypeInfo`** (reflect a type INTO a value — the inverse of
|
||||
`define`'s decode; widen `TypeInfo` past `` `enum `` + construct a `[]EnumVariant`
|
||||
value in the interp; its own focused effort) and **validation + loud diagnostics**
|
||||
(dup variants, by-value self-ref, never-defined `declare`, use-before-define).
|
||||
|
||||
## Known issues
|
||||
None.
|
||||
|
||||
## Log
|
||||
- **declare/define floor established.** The comptime type-construction surface is
|
||||
two primitives (`declare`/`define`); all named constructors are sx. A `::` binding
|
||||
or type-fn body that calls a `Type`-returning fn is comptime-evaluated (the
|
||||
builtins mint the type) — no syntactic constructor recognition in the compiler.
|
||||
Name travels in `TypeInfo`. Examples 0614 (one-shot) / 0615 (type-fn identity) /
|
||||
0617 (channel results) run on the floor; `field_type` reflection (0616) unchanged.
|
||||
Full suite green (673).
|
||||
- **Stream carved (earlier).** Selected as the first async-first foundation: gates
|
||||
channel result types (`RecvResult($T)`) and `race`'s synthesized union, fully
|
||||
validated, self-contained, testable in isolation (`06xx` comptime).
|
||||
Reference in New Issue
Block a user