From 14486dd78f0c05195fca6a8561c2f045a8d4ca10 Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 28 May 2026 03:14:12 +0000 Subject: [PATCH] =?UTF-8?q?go:=20Phase=2010=20closed=20=E2=80=94=20sister?= =?UTF-8?q?=20plans=20cross-referenced=20[nothing]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit plans/lib-guest-scheduler.md and plans/lib-guest-static-types- bidirectional.md both have Phase 1 ticked complete from Go's side with status blocks enumerating what landed. Each sister diary received a consolidated chisel-summary entry: the kit primitives the Go consumer chiselled out, the three pluggable predicates / orthogonal first-class-tag axes, and the v0 limitations the eventual kit must lift. No new Go code — Phase 10 is doc-only per plan. Go-on-SX loop fully landed: 11 phases, 7 test suites, 609/609 passing. Two-consumer rule per sister plan now waits on TypeScript (Phase 2 of the bidirectional sister plan, owned outside this loop). Co-Authored-By: Claude Opus 4.7 (1M context) --- plans/go-on-sx.md | 36 +++++++-- plans/lib-guest-scheduler.md | 55 ++++++++++++- plans/lib-guest-static-types-bidirectional.md | 78 ++++++++++++++++++- 3 files changed, 160 insertions(+), 9 deletions(-) diff --git a/plans/go-on-sx.md b/plans/go-on-sx.md index 9bd769ad..26e25742 100644 --- a/plans/go-on-sx.md +++ b/plans/go-on-sx.md @@ -432,15 +432,21 @@ Progress-log line → push `origin/loops/go`. - [ ] WaitGroup variants (deferred to Phase 8b — sync package). - **Acceptance:** e2e/ suite at 10+ tests — **cleared (12/12).** -### Phase 10 — lib/guest extraction enabler ⬜ +### Phase 10 — lib/guest extraction enabler ✅ - Now that Go has lex+parse+types+eval+sched, sister plans are unblocked on the Go side. This phase is **doc-only** in `loops/go`: - - Cross-reference `plans/lib-guest-scheduler.md` — mark its Phase 1 - (Go scheduler independent) as complete from Go's side. - - Cross-reference `plans/lib-guest-static-types-bidirectional.md` — - mark its Phase 1 as complete from Go's side. - - Update the chiselling diary in each sister plan with the actual - Go-side surface that emerged. + - [x] Cross-reference `plans/lib-guest-scheduler.md` — Phase 1 marked + complete from Go's side; status block enumerates the chan + primitive shape, defer + panic-cell mechanics, v0 sync-spawn + caveat, and the cross-cutting abstractions chiselled. + - [x] Cross-reference `plans/lib-guest-static-types-bidirectional.md` — + Phase 1 marked complete; status block enumerates synth/check, + untyped-constant 3-tier flow, structural-interface satisfaction, + generics with opaque `:ty-param`, and the index-synth shape. + - [x] Both diaries received a consolidated Go-side-surface entry + listing the kit primitives that emerged, the three pluggable + predicates / orthogonal first-class-tag axes, and the v0 + limitations the kit must lift. - **Acceptance:** sister plans cross-referenced + diaries updated. No new Go code. @@ -634,6 +640,22 @@ Minimal repro: see `lib/go/lex.sx#gl-oct-digit?` and `#gl-match-op`. _Newest first. Append one dated entry per commit._ +- 2026-05-28 — **Phase 10 closed — sister plans cross-referenced.** + Both `plans/lib-guest-scheduler.md` and `plans/lib-guest-static- + types-bidirectional.md` now have Phase 1 ticked complete with + status blocks enumerating exactly what landed on Go's side: chan + primitive shape, defer + panic-cell mechanics, v0 sync-spawn + caveat (scheduler); synth/check + untyped-constant flow + iface + satisfaction + generics + index synth (types). Both diaries + received a consolidated chisel-summary entry listing the kit + primitives the Go consumer chiselled out, the three pluggable + predicates / orthogonal first-class-tag axes, and the v0 + limitations the eventual kit must lift. No new Go code — this + iteration is doc-only as the plan specifies. **Go-on-SX loop + fully landed: 11 phases, 7 test suites, 609/609 passing.** The + two-consumer rule on each sister plan now waits on Erlang + (already done) and TypeScript (Phase 2 of the bidirectional + sister plan, owned outside this loop). [nothing] - 2026-05-28 — **Phase 9 closed (e2e 12/12, +10 cleared, total 609/609).** Twelve canonical Go programs running end-to-end across the full pipeline (lex+parse+types+eval+sched+stdlib): sieve via diff --git a/plans/lib-guest-scheduler.md b/plans/lib-guest-scheduler.md index 2b09f23a..e7c5db0f 100644 --- a/plans/lib-guest-scheduler.md +++ b/plans/lib-guest-scheduler.md @@ -144,13 +144,22 @@ This is a long-running plan paced against Go-on-SX. Phases are not loop-style - **Output:** clear-eyed mental model. Without this, we'll merge Erlang's scheduler shape into the kit and pretend it generalises. -### Phase 1 — Go scheduler independent implementation ⬜ +### Phase 1 — Go scheduler independent implementation ✅ - During Go-on-SX, implement `lib/go/sched.sx` from scratch. Do NOT look at Erlang's scheduler while doing this. (Or read it once, then close it.) - Pass Go's channel + goroutine + select conformance tests. - **Acceptance:** Go scheduler green, lib/go/scoreboard.json includes scheduler tests, two-consumer rule now passable. - **Output:** two independent, working implementations of the same idea. +- **Status (2026-05-28):** Done. `lib/go/sched.sx` ships channels as + closure-bundles `(:go-chan SEND RECV CLOSED? CLOSE! LEN)` sharing a + mutable buffer + closed flag. Goroutines: `go` stmt is v0-synchronous + (no real preemption — flagged Phase 5b). select dispatches by source + order picking first ready case; default makes it non-blocking; + blocking-no-default returns `:select-blocked-no-default` sentinel. + 40 runtime tests + 12 e2e programs use the scheduler primitives. + **Two-consumer rule passable** — Erlang's scheduler and Go's + scheduler both exist as independent implementations. ### Phase 2 — Diff and proposed kit ⬜ - Side-by-side diff: Erlang's scheduler vs Go's scheduler. Where do they @@ -231,6 +240,50 @@ real result. _Newest first. Append one dated entry per milestone landed._ +- 2026-05-28 — **Go-on-SX consumer-side surface fully landed (609/609 + tests across 7 suites).** This is the Phase-10 cross-reference + entry: with all of Go's lex+parse+types+eval+sched+stdlib+e2e + proven independent of the eventual kit, the scheduler-kit + surface that emerged from this consumer is: + + **Primitives (locked in):** + 1. `(:go-chan SEND RECV CLOSED? CLOSE! LEN)` — closures-over- + mutable-state channel. Identity matters (distinct `make()` + calls produce distinct closures, `(= ch1 ch2)` false). + 2. `(:go-defer CALLEE FROZEN-ARGS)` — frame-attached cleanup + record. Args evaluated at defer-time; call deferred to + frame exit. + 3. `__go-defer-stack` — frame-local mutable list of + defer records. Drained LIFO at frame exit by `go-run-defers!`. + 4. `__go-panic-cell` (STATE V) — frame-attached out-of-band + channel. STATE ∈ {:none, :raised, :recovered}. `recover()` + walks env chain to find the outermost :raised cell. + 5. `(:go-panic V)` — propagating sentinel. + 6. v0 stub `after(d)` — channel already buffered with `:tick`. + Real time becomes a refinement of *when* readiness flips, + not of the protocol. + + **Cross-cutting abstractions (chiselled):** + - **Readiness protocol** (sched-pick): `select` consults + `ready?` over its cases; send/recv/timer/etc. all factor + through one predicate. See 2026-05-27 entry. + - **Frame-cleanup queue vs scheduler ready-queue** — distinct + orthogonal slots; conflating them was an early temptation + and stays explicit in the design. + - **Control-flow sentinels unify** at every AST boundary + (block, for, range-for, stmt-catch-all, program-loop): each + needs the same `propagates?` predicate inline. Kit should + expose ONE helper instead of N inline arms. + + **v0 limitations the kit must lift** (durable in commit trail): + - Real preemption (Phase 5b — needs reified execution state) + - Buffered/unbuffered channel distinction (currently unbounded) + - select fairness (currently source-order; spec wants random) + - Real-time clocks for `after` + + Next sister-plan-owned step is Phase 2 (diff + propose kit) + with Erlang's existing scheduler as the second consumer. + - 2026-05-27 — **Phase 6 closed: control-flow-sentinel unification observation.** After wiring panic propagation through 4 sites (go-eval-block, go-eval-for, go-eval-stmt's catch-all, go-eval- diff --git a/plans/lib-guest-static-types-bidirectional.md b/plans/lib-guest-static-types-bidirectional.md index e4e294d7..01d8266f 100644 --- a/plans/lib-guest-static-types-bidirectional.md +++ b/plans/lib-guest-static-types-bidirectional.md @@ -182,7 +182,7 @@ in the language. Specifically: show up between Go and the second consumer. - **Acceptance:** survey committed to this plan. No code. -### Phase 1 — Go independent implementation ⬜ +### Phase 1 — Go independent implementation ✅ - During Go-on-SX, implement `lib/go/types.sx` from scratch. Do not write with extraction in mind — write the simplest Go-specific bidirectional checker. @@ -193,6 +193,28 @@ in the language. Specifically: - **Acceptance:** Go conformance scoreboard includes type-checker tests, all passing. - **Output:** one consumer. Two-language rule still not met; no extraction. +- **Status (2026-05-28):** Done. `lib/go/types.sx` ships: + - **synth/check skeleton:** `go-synth` + `go-check` with first-class + error tags `(:type-error TAG ARGS...)`. + - **Untyped constants:** `:ty-untyped-int`, `:ty-untyped-float`, + `:ty-untyped-string`, `:ty-untyped-rune`. Canonical pitfall + handled — `var x float64 = 42 / 7` keeps untyped-int through + the divide. `go-unify-untyped` pairs untyped-int+float → float. + - **Interface satisfaction:** structural method-set match via + `#method/TYPE/NAME` mangled keys; `go-iface-satisfies?`. + - **Generics (Phase 7 closed):** `[T any]` / `[T, U any]` / + `[T any, U comparable]` parsed + type-checked; opaque + `(:ty-param NAME CONSTRAINT)` binding via + `go-extend-with-type-params`. Type-set constraints (`int | + float64`, `~int`) deferred — needs constraint-satisfaction + predicate (chiselled as the kit's 3rd pluggable predicate + slot). + - **Index synth:** `(:index OBJ IDX)` for slice/array/map → element + type. Same AST, 3 role-validators (the "shape is parser, role + is validator" lemma at scale). + 102 types tests pass. Two-language rule still pending: the bidirectional + kit needs a SECOND consumer (TS/Rust/typed-Scheme) before extraction. + Phase 2's "pick + start" is the next sister-plan-owned step. ### Phase 2 — Pick + start the second consumer ⬜ - Decide between TS, Rust-subset, or typed-Scheme-subset. Recommendation: @@ -282,6 +304,60 @@ The kits compose; design accordingly. _Newest first. Append one dated entry per milestone landed._ +- 2026-05-28 — **Go-on-SX consumer-side surface fully landed (609/609 + tests across 7 suites).** This is the Phase-10 cross-reference + entry: with all of Go's lex+parse+types+eval+sched+stdlib+e2e + proven independent of the eventual kit, the type-system-kit + surface that emerged from this consumer is: + + **Three pluggable predicates** (the kit's role-validator slots): + 1. **`synth(ctx, expr) → ty | error`** — type synthesis from + expression structure. Go's instance handles literals, + binops, applications, indexing, composites, etc. + 2. **`assignable?(got, expected) → bool`** — variance + untyped- + constant rules. Go's instance handles 3-tier untyped flow + (`untyped-int → int → float64` only in specific contexts). + 3. **`constraint-satisfies?(ty, constraint) → bool`** — does + a type fit a constraint? Go: interfaces (structural method + set), `comparable`, `any`. TS would: structural subtyping. + Haskell: typeclass dictionary resolution. Rust: trait impl. + + **Three orthogonal first-class-tag axes** (clean separation): + - **AST nodes** (parser output): `:func-decl`, `:literal`, + `:literal-string`, `:app`, `:index`, `:composite`, etc. + - **Value-type kinds** (evaluator output): `:go-struct`, + `:go-slice`, `:go-map`, `:go-chan`, `:go-fn`, `:go-method`, + `:go-builtin`, `:go-builtin-fn`, `:go-package`, `:go-panic`, + `:go-defer` — 11 kinds. All shape: `(:KIND PAYLOAD...)`. + - **Sentinel signals** (control-flow): `:return-value`, `:break`, + `:continue`, `:eval-error`, `:go-panic`. + + All three axes use the same `(first x) == :TAG` discipline. + Kit's `kind?` and `kind-of` predicates work uniformly. + + **The "shape is parser, role is validator" lemma**, validated + across THREE deliverables: + 1. Binding-groups (`(:field NAMES TY)`): 6 consumers (struct + fields, var-decls, const-decls, params, receivers, + type-params), 5 distinct roles (value-typing, value-pinning, + constraint-binding, kind-binding, trait-binding). + 2. Control-flow sentinels: same predicate dispatch at 4+ sites. + 3. Index synthesis (`(:index OBJ IDX)`): same AST, 3 role- + validators (slice / array / map). + + **v0 limitations the kit must lift** (durable in commit trail): + - Type-set constraints (`int | float64`, `~int`) — needs + constraint-satisfies? predicate real implementation. + - Type inference at call sites — Go's algorithm; currently + relies on type erasure at eval. + - nil-as-unbound — env-lookup needs an "absent" sentinel. + - First-char literal classification (was a bug; fixed by + `:literal-string` parser tag). + + Next sister-plan-owned step is Phase 2 (pick + start second + consumer — recommendation: TypeScript). Two-language rule + still pending until the second consumer lands. + - 2026-05-28 — From Go-on-SX Phase 8 first slice — **value-type kinds confirm the "kind-tag + payload" shape as cross-runtime primitive.** When the stdlib landed, packages joined the existing