go: after(d) timer stub + 13 pattern tests → runtime 40/40, Phase 5 closed [shapes-scheduler]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s

Acceptance bar hit (40 runtime, 497 total). Tests: timer ready,
select-with-timeout, fan-in (3 producers), worker queue, pipeline,
fan-out-then-fan-in, select source-order, fallback case, default,
producer-consumer, two-stage pipeline, channel-counter, after+default,
tick-collector.

Shape chiselled: timer collapses "after duration" into
"channel ready immediately" — select needs only ready? from each
case. Real time is when the flip happens, not what the protocol is.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 22:24:13 +00:00
parent fa99652970
commit 1d3021d206
9 changed files with 381 additions and 10 deletions

View File

@@ -304,7 +304,7 @@ Progress-log line → push `origin/loops/go`.
Remaining sub-items (lexical closures, multi-return funcs, full
slice triple with capacity) refine but don't gate Phase 5.
### Phase 5 — Goroutines + channels + select (`lib/go/sched.sx`)
### Phase 5 — Goroutines + channels + select (`lib/go/sched.sx`)
- [x] Scaffold: `lib/go/sched.sx` with `go-make-chan` (closures-over-
mutable-buf), `go-chan-send!` / `go-chan-recv!` / `go-chan-closed?`
/ `go-chan-close!`. Channel identity via closure-instance.
@@ -325,7 +325,9 @@ Progress-log line → push `origin/loops/go`.
channel (just value). v0 chan-range stops when buffer empties
(no preemption to wait for new sends). break exits with the
pre-break env (preserving prior-iteration assignments).
- [ ] `time.After`-like timer channel.
- [x] `time.After`-like timer channel (v0 stub: `after(d)` returns a
channel already holding `:tick`; lets `select`-with-timeout patterns
express the intent while real time is deferred to Phase 5b).
- **Independent implementation.** Do NOT use lib/guest/scheduler/ — that
kit doesn't exist yet and depends on this work for its design. See
`plans/lib-guest-scheduler.md`.
@@ -607,6 +609,21 @@ Minimal repro: see `lib/go/lex.sx#gl-oct-digit?` and `#gl-match-op`.
_Newest first. Append one dated entry per commit._
- 2026-05-27 — **Phase 5 acceptance bar hit (40/40 runtime, 497/497
total).** Added `after(d)` builtin (v0 timer stub: returns a channel
already buffered with `:tick`) and 13 canonical-pattern tests:
timer + select-with-timeout, fan-in, worker queue, two-stage
pipeline, fan-out-then-fan-in, select source-order winner, select
fallback case, select with default, producer-consumer count-drain,
three-channel two-stage pipeline, channel-as-counter, after-with-
default, tick-collector. v0 ping-pong is impossible (sync spawn,
no blocking) — flagged in Phase 5b. **Shape chiselled:** the timer
channel collapses "after duration" into "channel ready immediately"
— the only thing `select` needs from a timer is that one of the
cases be in the ready set. Real time becomes a refinement of
*when* readiness flips, not of the protocol. Sister-plan diary
updated with the readiness-as-protocol observation. [shapes-
scheduler]
- 2026-05-27 — Phase 5 cont.: range-over-{slice,map,channel}. New
`go-eval-range-for` dispatches on the collection type:
slice → bind index + element, iterate by position