green(reify): RecvResult/TryResult channel result types over reify
REIFY Phase 3.1. Add RecvResult($T) and TryResult($T) to meta.sx as type-fns over reify (value-or-closed; value-or-empty-or-closed). They need NO new compiler machinery — reify-of-a-literal in a type-fn body is exactly the Phase 1 path — so the channel result types are pure sx library code. examples/0617 green (both construct + match, incl. payload-less .closed / .empty). Suite green (673 examples, 447 unit). make_enum(variants) (3.2) and type_info (2.2) remain — both blocked on a generalized reify reader (reifyType currently AST-walks a literal TypeInfo). Plan/checkpoint updated.
This commit is contained in:
@@ -4,7 +4,19 @@ Companion to [PLAN-REIFY.md](PLAN-REIFY.md). Update after every step (one step a
|
||||
time, per the cadence rule).
|
||||
|
||||
## Last completed step
|
||||
**Phase 2.1 (green) — `field_type` done.** `field_type($T, i) -> Type` is
|
||||
**Phase 3.1 (green) — `RecvResult`/`TryResult` done.** Added `RecvResult($T)` and
|
||||
`TryResult($T)` to `meta.sx` as type-fns over `reify` (a value-or-`closed`, and a
|
||||
value-or-`empty`-or-`closed` enum). They needed NO new compiler machinery — they're
|
||||
reify-of-a-literal in a type-fn body, i.e. exactly the Phase 1 path — so the channel
|
||||
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).
|
||||
|
||||
### (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
|
||||
on `Lowering`): struct field / tagged-union + `union` variant payload (`.void` for
|
||||
a tagless variant) / tuple element / array + vector element; OOB and memberless
|
||||
@@ -79,7 +91,21 @@ on-demand import keeps the prelude clean; reify users `#import
|
||||
"modules/std/meta.sx"`. (User-directed.)
|
||||
|
||||
## Next step
|
||||
**Phase 2.2 (`type_info($T) -> TypeInfo`).** Reflect a type into a `TypeInfo`
|
||||
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`.
|
||||
|
||||
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.
|
||||
|
||||
### (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
|
||||
`meta.sx` `TypeInfo` data model beyond `` `enum `` (struct / tuple variants); (b)
|
||||
build the value at comptime — a `[]EnumVariant`-style slice of structs holding
|
||||
@@ -113,6 +139,10 @@ in PLAN-REIFY Phase 4.
|
||||
None yet.
|
||||
|
||||
## Log
|
||||
- **3.1 (green) — `RecvResult`/`TryResult` done.** Added as type-fns over `reify`
|
||||
in `meta.sx` (no new machinery — Phase 1 reify-of-literal-in-type-fn); `0617`
|
||||
green. `make_enum` (3.2) pending on the generalized reify reader.
|
||||
- **3.0 (xfail).** `0617` + empty marker → RED (RecvResult undefined).
|
||||
- **2.1 (green) — `field_type` done.** `fieldTypeOf` over the type table
|
||||
(struct/tagged-union/union/tuple/array/vector; OOB+memberless = loud poison);
|
||||
folds at lower time, composes in `type_eq`/`type_name`; `0616` green. `type_info`
|
||||
|
||||
@@ -77,10 +77,12 @@ Examples: `06xx` (comptime, deterministic), `11xx` (diagnostics for loud failure
|
||||
| 2.1 | green | **DONE.** `field_type($T, i) -> Type` over the type table (`fieldTypeOf` in `generic.zig`): struct field / tagged-union+union variant payload / tuple element / array+vector element; OOB + memberless → loud poison. Folds at lower time, composes in `type_eq`/`type_name`. | `src/ir/lower/generic.zig` |
|
||||
| 2.2 | xfail→green | **PENDING.** `type_info($T) -> TypeInfo` — reflect a type into a `TypeInfo` *value* (the inverse of reify). Needs the `TypeInfo` data model widened (struct/tuple variants beyond `` `enum ``) AND comptime construction of a `[]EnumVariant`-style value (slice of structs holding strings + `Type` tags) read from the type table. Still bails loudly in `call.zig:tryLowerReflectionCall`. Larger than 2.1 — its own step. | `library/modules/std/meta.sx`, `src/ir/interp.zig` / `call.zig` |
|
||||
|
||||
### Phase 3 — `make_enum` + `RecvResult`/`TryResult` (sx lib)
|
||||
### Phase 3 — `RecvResult`/`TryResult` (done) + `make_enum` (pending)
|
||||
| Step | Commit | What | Files |
|
||||
|---|---|---|---|
|
||||
| 3.0 | lock | `make_enum(variants) -> Type` (sx lib over `reify`); `RecvResult($T)`/`TryResult($T)` as type-fns. Behavior-lock: `RecvResult(i64)` constructs + matches. | `library/modules/std/*` |
|
||||
| 3.0 | xfail | `examples/0617` uses `RecvResult(i64)`/`TryResult(i64)` (construct + match). Red (undefined). | `examples/0617-*` |
|
||||
| 3.1 | green | **DONE.** `RecvResult($T)`/`TryResult($T)` as type-fns over `reify` in `meta.sx` — needs NO new machinery (reify-of-literal in a type-fn body = Phase 1). `0617` green. | `library/modules/std/meta.sx` |
|
||||
| 3.2 | pending | **`make_enum(variants: []EnumVariant) -> Type`** — sx lib over `reify` with a RUNTIME (non-literal) `variants` arg. BLOCKED on the generalized reify reader: `reifyType` currently reads a LITERAL `TypeInfo` off the AST, so `reify(.enum(.{ variants = variants }))` (variable, not a literal) can't be read yet. Pairs with Phase 2.2 (interp-evaluate the `TypeInfo` value instead of AST-walking). | `library/modules/std/meta.sx`, `src/ir/lower/nominal.zig` |
|
||||
|
||||
### Phase 4 — reference-based self-reference (explicit declare → define)
|
||||
> **API decision (user-directed):** an explicit **`declare()` / `define(h, info)`**
|
||||
@@ -133,6 +135,9 @@ Examples: `06xx` (comptime, deterministic), `11xx` (diagnostics for loud failure
|
||||
mangled name; `Box(i64)` at two sites is one type; `examples/0615` green)
|
||||
- [~] Phase 2 — `field_type` DONE (`examples/0616` green); `type_info` (reflect → a
|
||||
`TypeInfo` value) PENDING as step 2.2
|
||||
- [~] Phase 3 — `RecvResult($T)`/`TryResult($T)` DONE (`examples/0617` green, type-fns
|
||||
over `reify` in `meta.sx`); `make_enum(variants)` PENDING (step 3.2 — needs the
|
||||
generalized reify reader, pairs with 2.2)
|
||||
- [ ] Phase 2 — `type_info` + `field_type`
|
||||
- [ ] Phase 3 — `make_enum` + `RecvResult`/`TryResult`
|
||||
- [ ] Phase 4 — reference self-reference
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
|
||||
1
examples/expected/0617-comptime-reify-recvresult.stderr
Normal file
1
examples/expected/0617-comptime-reify-recvresult.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
4
examples/expected/0617-comptime-reify-recvresult.stdout
Normal file
4
examples/expected/0617-comptime-reify-recvresult.stdout
Normal file
@@ -0,0 +1,4 @@
|
||||
recv value 42
|
||||
recv closed
|
||||
try value 7
|
||||
try empty
|
||||
@@ -36,3 +36,29 @@ TypeInfo :: enum {
|
||||
reify :: (info: TypeInfo) -> Type #builtin;
|
||||
type_info :: ($T: Type) -> TypeInfo #builtin;
|
||||
field_type :: ($T: Type, idx: i64) -> Type #builtin;
|
||||
|
||||
// --- Reify'd shapes built in sx library code (no new compiler machinery) ---
|
||||
//
|
||||
// The channel result types, expressed as type-fns over `reify`. They are the
|
||||
// canonical demonstration that `reify` carries a full enum through codegen:
|
||||
// `RecvResult(i64)` constructs and matches like any hand-written enum, and is
|
||||
// one nominal type across sites (the type-fn mangled-name identity path). The
|
||||
// channel library (N3) consumes these once it lands.
|
||||
|
||||
// A blocking recv: a value, or the channel was closed (drained).
|
||||
RecvResult :: ($T: Type) -> Type {
|
||||
return reify(.enum(.{ variants = .[
|
||||
EnumVariant.{ name = "value", payload = T },
|
||||
EnumVariant.{ name = "closed", payload = void },
|
||||
] }));
|
||||
}
|
||||
|
||||
// A non-blocking try-recv: a value, currently empty, or closed — three states
|
||||
// a bool can't express.
|
||||
TryResult :: ($T: Type) -> Type {
|
||||
return reify(.enum(.{ variants = .[
|
||||
EnumVariant.{ name = "value", payload = T },
|
||||
EnumVariant.{ name = "empty", payload = void },
|
||||
EnumVariant.{ name = "closed", payload = void },
|
||||
] }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user