plan(reify): re-architect onto declare/define as the only compiler primitive
User-directed redirection. The compiler should expose ONLY declare() and
define(handle, info) as comptime type-table primitives; reify / make_enum /
RecvResult / TryResult all become plain sx in meta.sx (reify ==
{ h := declare(); define(h, info); return h; }). The AST-walking reifyType
and every syntactic reify recognition (decl.zig E :: reify hook, generic.zig
findReturnReifyCall routing) are to be DELETED, replaced by generic comptime
evaluation of a Type-returning expression.
PLAN-REIFY gains a RE-ARCHITECTURE section: the irreducible compiler floor
(declare = empty nominal slot; define = decode a TypeInfo VALUE + fill via
updatePreservingKey; comptime-eval a Type-returning ::-RHS/type-fn body),
the resolved naming/identity story (declare mints anonymous, the binding site
names it; identity via the existing instantiation cache), and an F1-F5 phase
table that re-greens 0614/0615/0617 on the floor.
No code change in this commit — the in-session Phase 3.2 attempt (make_enum +
eval-decode reader) was reverted (reset to 9306ad5) so the floor is built
first. Checkpoint records the revert + sets next step = F1.
This commit is contained in:
@@ -12,9 +12,9 @@ result types are pure sx library code. `examples/0617` green (both construct +
|
||||
match, incl. payload-less `.closed`/`.empty`). Full suite green (673 examples).
|
||||
Cadence: 3.0 xfail (undefined → RED) → 3.1 green.
|
||||
|
||||
**`make_enum(variants)` NOT done** (Phase 3.2): it takes a RUNTIME `[]EnumVariant`,
|
||||
so `reify(.enum(.{ variants = variants }))` is a non-literal arg — blocked on the
|
||||
generalized reify reader (pairs with 2.2). **`type_info` NOT done** (Phase 2.2).
|
||||
**Phase 3.1 is the last GREEN step.** Phase 3.2 was attempted + reverted; the stream
|
||||
now pivots to the `declare`/`define` RE-ARCHITECTURE (see the section below + the
|
||||
F1–F5 table in PLAN-REIFY). **`type_info` NOT done** (old Phase 2.2, orthogonal).
|
||||
|
||||
### (prior) Phase 2.1 (green) — `field_type` done. `field_type($T, i) -> Type` is
|
||||
implemented over the type table (`fieldTypeOf` in `lower/generic.zig`, re-exported
|
||||
@@ -90,20 +90,35 @@ type table and shifts every `.ir` snapshot (broke 37 examples in a trial). An
|
||||
on-demand import keeps the prelude clean; reify users `#import
|
||||
"modules/std/meta.sx"`. (User-directed.)
|
||||
|
||||
## Next step
|
||||
Two pending pieces, both blocked on the SAME thing — **a generalized reify reader**
|
||||
(`reifyType` currently AST-walks a LITERAL `TypeInfo`; it can't read a computed /
|
||||
variable `TypeInfo`). Do that generalization (interp-evaluate the `TypeInfo` value,
|
||||
or a broader AST reader) and both unlock:
|
||||
- **Phase 3.2 — `make_enum(variants: []EnumVariant) -> Type`** (sx lib; `variants` is
|
||||
a runtime value, not a literal).
|
||||
- **Phase 2.2 — `type_info($T) -> TypeInfo`** (reflect → a `TypeInfo` value; also
|
||||
needs the `TypeInfo` data model widened past `` `enum `` for struct/tuple). Bails
|
||||
loudly today in `call.zig:tryLowerReflectionCall`.
|
||||
## RE-ARCHITECTURE in progress (user-directed, 2026-06-16)
|
||||
**`declare`/`define` are to be the ONLY compiler primitives; `reify` / `make_enum` /
|
||||
`RecvResult` / `TryResult` move to sx in `meta.sx`.** `reify` becomes literally
|
||||
`{ h := declare(); define(h, info); return h; }`. The AST-walking `reifyType` and all
|
||||
syntactic `reify` recognition (`decl.zig` `E :: reify` hook, `generic.zig`
|
||||
`findReturnReifyCall`) get DELETED, replaced by generic comptime evaluation of a
|
||||
Type-returning expression. Full F1–F5 phase table + the resolved naming/identity
|
||||
design is in **PLAN-REIFY.md → "RE-ARCHITECTURE"**.
|
||||
|
||||
Remaining after that: **Phase 4** (self-reference via `declare()`/`define()` — API
|
||||
already decided), **Phase 5** (validation + loud diagnostics: dup variants, bad
|
||||
backing, by-value self-ref). Both are independent of the reader generalization.
|
||||
**A Phase 3.2 attempt (make_enum + an eval-decode reader, `reifyEnumFromVariantsValue`
|
||||
+ `reifyValueFn`) was implemented this session, then REVERTED** (`git reset --hard
|
||||
9306ad5`) per this decision — the reader grew the compiler instead of shrinking it.
|
||||
The eval-decode *decode logic* is salvage for `define` (see commit 4d6c463 in reflog
|
||||
if needed); the *syntactic routing* is discarded.
|
||||
|
||||
## Next step
|
||||
**F1 — `declare()`/`define()` primitives + a directly-minted RECURSIVE enum.**
|
||||
- `declare() -> Type`: intern an empty forward nominal slot (`reserveShadowEnumSlot`
|
||||
shape, `nominal.zig:98`), anonymous, return a first-class `Type`.
|
||||
- `define(handle, info)`: decode the `TypeInfo` *value* (reuse the reverted decode:
|
||||
interp `Value` → names + payload `Type`-tags → `tagged_union` matching
|
||||
`buildEnumInfo`), fill via `updatePreservingKey`.
|
||||
- `X :: declare()` decl hook + scan-time `define(...)` side-effect (must complete
|
||||
before codegen needs the layout — same scan-time window the old `reifyType` used).
|
||||
- Example: `List :: declare(); define(List, .enum(.{ … payload = *List … }))` —
|
||||
cons/nil list, construct + match. Self-ref works because the handle predates the body.
|
||||
Then F2 (reify→sx + general comptime-Type-decl eval, delete `reifyType`), F3 (type-fn
|
||||
body eval, delete `findReturnReifyCall`, re-green 0615/0617), F4 (make_enum in sx),
|
||||
F5 (validation). `type_info` (old 2.2) stays orthogonal/pending.
|
||||
|
||||
### (superseded) earlier Next step — `type_info` value construction Reflect a type into a `TypeInfo`
|
||||
*value* — the inverse of reify. Two sub-pieces, both non-trivial: (a) widen the
|
||||
|
||||
@@ -55,7 +55,57 @@ Examples: `06xx` (comptime, deterministic), `11xx` (diagnostics for loud failure
|
||||
|
||||
---
|
||||
|
||||
## Phases
|
||||
## RE-ARCHITECTURE (user-directed, 2026-06-16) — `declare`/`define` are the ONLY compiler primitives
|
||||
|
||||
**Decision:** the compiler must expose **only** the two comptime type-table
|
||||
primitives `declare()` and `define(handle, info)`. **`reify`, `make_enum`,
|
||||
`RecvResult`, `TryResult` all become plain sx** in `meta.sx` — `reify` is literally
|
||||
`{ h := declare(); define(h, info); return h; }`. The AST-walking `reifyType` and
|
||||
every *syntactic* recognition of `reify` (`decl.zig`'s `E :: reify(...)` hook,
|
||||
`generic.zig`'s `findReturnReifyCall` type-fn routing) are **deleted** — replaced by
|
||||
generic **comptime evaluation of a Type-returning expression**.
|
||||
|
||||
This supersedes the old builtin-`reify` approach of Phases 0/1/3 below (which are
|
||||
GREEN today but compiler-coupled). Phase 3.2 (`make_enum` + the eval-decode reader)
|
||||
was implemented then **reverted** (commit reset to 9306ad5) to rebuild on this floor.
|
||||
|
||||
### The irreducible compiler floor (cannot be sx — mints `TypeId`s / evaluates types)
|
||||
1. **`declare() -> Type`** — intern a fresh EMPTY forward nominal slot (unique
|
||||
`nominal_id`, anonymous name), return it as a first-class `Type` value. Reuses the
|
||||
`reserveShadowEnumSlot` shape (`nominal.zig:98`).
|
||||
2. **`define(handle: Type, info: TypeInfo)`** — decode the `TypeInfo` **value** (the
|
||||
reverted `reifyEnumFromVariantsValue` decode logic moves here: interp `Value` →
|
||||
names + payload `Type`-tags → `tagged_union` byte-identical to `buildEnumInfo`),
|
||||
fill the slot via `updatePreservingKey` (`types.zig:442`). Loud on bad input.
|
||||
3. **Comptime-evaluate a Type-returning `::` RHS / type-fn body** through the
|
||||
interpreter to a `type_tag`, then bind / rename / identity-cache. This is the new
|
||||
general capability that REPLACES the `reify`-name pattern-matching.
|
||||
|
||||
### Naming + identity (resolved)
|
||||
- `declare()` mints ANONYMOUS; the **binding site** names it: a direct `X :: <expr>`
|
||||
renames the handle to `X`; a type-fn instantiation renames to the mangled name.
|
||||
- **Identity (Contract 1)** still rides the existing `instantiateTypeFunction`
|
||||
mangled-name cache — `RecvResult(i64)` memoizes, body (hence `declare`) runs once.
|
||||
|
||||
### Floor phases (REPLACES old Phases 0/1/3; re-greens 0614/0615/0617)
|
||||
| Step | Commit | What | Files |
|
||||
|---|---|---|---|
|
||||
| F1.0 | xfail | `examples/06xx` mints a **recursive** enum directly: `List :: declare();` + `define(List, .enum(.{ variants = .[ … payload = *List … ] }))`; construct + match a cons/nil list. Red (declare/define undefined). | `examples/06xx-*` |
|
||||
| F1.1 | green | `declare`/`define` as comptime builtins + the `X :: declare()` decl hook + scan-time `define(...)` side-effect + the value-decode (from the reverted 3.2). Self-ref works because the handle predates the body. | `src/ir/lower/{decl,nominal}.zig`, `src/ir/interp.zig`, `meta.sx` |
|
||||
| F2.0 | xfail | Reimplement `reify` in `meta.sx` as `declare`+`define`+return; switch `E :: reify(...)` to the **general comptime-Type-expr** decl path; delete the `E :: reify` AST special-case + `reifyType` literal walk. Red until the general path lands. | `meta.sx`, `src/ir/lower/decl.zig` |
|
||||
| F2.1 | green | General comptime evaluation of a Type-returning `::` RHS (run interp → `type_tag` → rename/bind). `examples/0614` green again with ZERO `reify` knowledge in the compiler. | `src/ir/lower/decl.zig`, `src/ir/interp.zig` |
|
||||
| F3.0 | xfail | Delete `findReturnReifyCall` routing; make `instantiateTypeFunction` run a Type-returning body through the interp generally. Red for 0615/0617 until it lands. | `src/ir/lower/generic.zig` |
|
||||
| F3.1 | green | General type-fn body comptime-eval + rename to mangled name + identity cache. `examples/0615` (cross-site identity) + `0617` (RecvResult/TryResult) green on the floor. | `src/ir/lower/generic.zig` |
|
||||
| F4 | xfail→green | `make_enum(variants)` in `meta.sx` — now TRIVIAL (reify is sx, type-fns eval generally). New `examples/06xx` (inline + computed variants). | `meta.sx`, `examples/06xx-*` |
|
||||
| F5 | xfail→green | Validation + loud diagnostics: dup variant names, by-VALUE self-ref (`payload = List` not `*List` → "infinite size"), a `declare()` never `define()`d (hard error at end of comptime). | `src/ir/interp.zig` / `src/ir/types.zig`, `examples/11xx-*` |
|
||||
|
||||
> `type_info($T) -> TypeInfo` (old Phase 2.2 — reflect a type INTO a value) is
|
||||
> orthogonal to this floor and still pending; it CONSTRUCTS a `TypeInfo` value
|
||||
> (inverse of `define`'s decode). Round-trips through the floor once it lands.
|
||||
|
||||
---
|
||||
|
||||
## (SUPERSEDED by the re-architecture above) Original builtin-`reify` phases
|
||||
|
||||
### Phase 0 — `reify` of a flat enum (the core)
|
||||
| Step | Commit | What | Files |
|
||||
|
||||
Reference in New Issue
Block a user