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).
|
time, per the cadence rule).
|
||||||
|
|
||||||
## Last completed step
|
## 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
|
implemented over the type table (`fieldTypeOf` in `lower/generic.zig`, re-exported
|
||||||
on `Lowering`): struct field / tagged-union + `union` variant payload (`.void` for
|
on `Lowering`): struct field / tagged-union + `union` variant payload (`.void` for
|
||||||
a tagless variant) / tuple element / array + vector element; OOB and memberless
|
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.)
|
"modules/std/meta.sx"`. (User-directed.)
|
||||||
|
|
||||||
## Next step
|
## 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
|
*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)
|
`meta.sx` `TypeInfo` data model beyond `` `enum `` (struct / tuple variants); (b)
|
||||||
build the value at comptime — a `[]EnumVariant`-style slice of structs holding
|
build the value at comptime — a `[]EnumVariant`-style slice of structs holding
|
||||||
@@ -113,6 +139,10 @@ in PLAN-REIFY Phase 4.
|
|||||||
None yet.
|
None yet.
|
||||||
|
|
||||||
## Log
|
## 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
|
- **2.1 (green) — `field_type` done.** `fieldTypeOf` over the type table
|
||||||
(struct/tagged-union/union/tuple/array/vector; OOB+memberless = loud poison);
|
(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`
|
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.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` |
|
| 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 |
|
| 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)
|
### Phase 4 — reference-based self-reference (explicit declare → define)
|
||||||
> **API decision (user-directed):** an explicit **`declare()` / `define(h, info)`**
|
> **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)
|
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
|
- [~] Phase 2 — `field_type` DONE (`examples/0616` green); `type_info` (reflect → a
|
||||||
`TypeInfo` value) PENDING as step 2.2
|
`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 2 — `type_info` + `field_type`
|
||||||
- [ ] Phase 3 — `make_enum` + `RecvResult`/`TryResult`
|
- [ ] Phase 3 — `make_enum` + `RecvResult`/`TryResult`
|
||||||
- [ ] Phase 4 — reference self-reference
|
- [ ] 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;
|
reify :: (info: TypeInfo) -> Type #builtin;
|
||||||
type_info :: ($T: Type) -> TypeInfo #builtin;
|
type_info :: ($T: Type) -> TypeInfo #builtin;
|
||||||
field_type :: ($T: Type, idx: i64) -> Type #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