docs: PLAN-RACE — composition gap fixed, synthesis proven; next is the race runtime in sched.sx

This commit is contained in:
agra
2026-06-26 13:41:42 +03:00
parent eb18bbc6fd
commit 6dcb620b48

View File

@@ -75,14 +75,19 @@ Prereqs DONE (each committed + adversarially reviewed + suite-green):
`($T) -> Type` builder can `inline for 0..field_count(T)` and size `[field_count(T)]EnumVariant`.
Verified: the variable-arity loop + array dim now work inside `RaceResult`.
**NEXT BLOCKER (step 2, not yet resolved): nested comptime-type-call composition.** Building each
variant payload needs `*Task(A) → A`, i.e. `field_type(pointee(field_type(T, i)), 0)`. Today:
- passing a `field_type(...)` RESULT as the type-arg to a generic (`TaskResult(field_type(T, i))`) →
*"cannot infer generic type parameter 'P'"*;
- the same nested inline (`field_type(pointee(field_type(T, i)), 0)`) → *"cannot infer 'T' for
field_type"*;
- a `::` alias bound to a comptime-type-call result (`P0 :: field_type(NT, 0)`) → *"unresolved type
'P0'"* (kin to issue 0196).
So a comptime-type-call's Type result isn't usable as a generic type-arg / `::` alias / nested
type-call arg. This composition gap is the next thing to fix (or design around) before the variable-
arity `RaceResult` payloads can be built. Everything up to the payload projection works.
- **comptime type-call composition** fixed (`eb18bbc6`) — a `field_type(...)`/`pointee(...)` result is
now usable as a `Type`-typed struct-field value, a generic `$P: Type` arg, and a nested type-call
arg (incl. with an `inline for` loop-var index). The **variable-arity `RaceResult` synthesis works
end-to-end** (proven by `examples/comptime/0649-comptime-typecall-composition.sx`: reflect a named
tuple of `*Box(..)` handles → mint a tagged-union with the tuple's labels, projecting `*Box(A)``A`).
**All comptime prerequisites are now in place — the rest is pure-sx library work in sched.sx.**
**NEXT (step 24): the actual `race` in `library/modules/std/sched.sx`.**
- `RaceResult :: ($T) -> Type` over `*Task(..)` (the 0649 shape, with `Task` instead of `Box`).
- `race :: ufcs (self: *Scheduler, tasks: $T) -> RaceResult(T)`: suspend the caller until the FIRST
task is `.ready`; build the winner variant (construct the minted union by the winning index/label —
watch for a possible variant-construction-by-dynamic-index gap); then `cancel` + `wait`-join every
loser before returning (structured). Reuses `suspend_self`/`wake` + `Task.cancel`/`wait`.
- Lock with a 2/3-task example (deterministic winner via `sleep` ordering, asserting losers cancelled).
- Validate byte-identical on aarch64-macOS host AND aarch64-linux container; full `zig build test`.