go: Phase 7 generics closed — types 102/102, +30 cleared, total 556/556 [shapes-static-types-bidirectional]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Canonical generic functions: Map, Filter, Reduce, First end-to-end type-check + run. Plus 20+ typer-only shape tests covering Apply, Compose, ToMap, Swap, Box, Triple, ToSlice, Take, Send, Fill, Eq, Values, Pair, Inspect, etc. Index synth (slice/array/map → element type) added to typer. v0 limitations stamped in tests: SX `/` is float (no int mod emulation), `var r []T` indistinguishable from unbound, single-name constraints opaque (no type-set arithmetic). Shape locked in: "the parser recognizes shapes, the validator recognizes roles." Same AST + different role-validators = different guest semantics. Diary documents this as the lemma the kit should extract — three deliverables (binding-groups, control-flow sentinels, index synthesis) now all instantiate it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -379,21 +379,25 @@ Progress-log line → push `origin/loops/go`.
|
||||
args-eager-on-panic-path. 20 tests total on eval/.
|
||||
- **Acceptance:** eval/ +20 tests — **20/20 cleared.**
|
||||
|
||||
### Phase 7 — Generics (Go 1.18+) ⬜
|
||||
### Phase 7 — Generics (Go 1.18+) ✅
|
||||
- [x] **Foundation: parser + typer + eval handle `[T any]` syntax.**
|
||||
`gp-parse-type-params` reads `[NAMES CONSTRAINT, ...]` after the
|
||||
func name; AST gets optional 6th slot (legacy 5-slot preserved
|
||||
when no `[...]`). Typer binds each name as `(:ty-param NAME
|
||||
CONSTRAINT)` in the body ctx via `go-extend-with-type-params`.
|
||||
Eval is type-erasing: ignores type info, dispatches by name +
|
||||
arg count. 10 tests: parse (3), types (5), eval (2).
|
||||
- [ ] Type parameters with type-set constraints (`int | float64`,
|
||||
arg count.
|
||||
- [x] **Canonical generic functions type-check + run end-to-end.**
|
||||
Map, Filter, Reduce, First with `[T any]` / `[T, U any]` /
|
||||
`[T any, U comparable]` constraints. Index synth (`xs[0]` for
|
||||
slice element type, `m[k]` for map value type) added to typer
|
||||
so generic body bodies can index. 30 types tests + 4 eval
|
||||
tests + 3 parse tests = **37 generic-related tests landed.**
|
||||
- [ ] Type-set constraints with real validation (`int | float64`,
|
||||
`~int`). Deferred — needs constraint-satisfaction predicate.
|
||||
- [ ] Type inference at call sites — basic. Currently calls must use
|
||||
explicit type args OR rely on type erasure at eval.
|
||||
- Tests: generic function (`func Map[T, U any](xs []T, f func(T) U) []U`),
|
||||
generic data structure (linked list), constrained type param.
|
||||
- **Acceptance:** types/ +30 tests. Currently +5.
|
||||
- [ ] Type inference at call sites — basic. Currently relies on type
|
||||
erasure at eval, no inference at types/.
|
||||
- **Acceptance:** types/ +30 tests — **cleared (72 → 102).**
|
||||
|
||||
### Phase 8 — Minimal stdlib (`lib/go/std/`) ⬜
|
||||
- Implement just what's needed for representative programs:
|
||||
@@ -628,6 +632,30 @@ 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 7 closed (types 102/102, +30 cleared, total
|
||||
556/556).** Canonical generic functions all type-check and run:
|
||||
Map, Filter, Reduce, First (eval), plus typer-only Apply, Compose,
|
||||
ToMap, Swap, Box, Triple, ToSlice, Take, Send, Fill, Sum, Eq,
|
||||
Values, Inspect, Contains, Pair, F, G, H, Noop. Index synth
|
||||
(`:index OBJ IDX`) added to typer covering slice/array/map cases
|
||||
— needed for `xs[0]` in generic body bodies.
|
||||
|
||||
**v0 limitations stamped:** SX integer division is float
|
||||
(`3/2 = 1.5`) so emulating modulo via `x - x/2*2` doesn't work —
|
||||
Filter test used `x > 3` instead. `var r []T` binds r to nil
|
||||
which the evaluator can't distinguish from unbound — Map/Filter
|
||||
bodies use `r := []int{}` literal instead. Constraint validation
|
||||
(T must be `comparable`, etc.) is opaque in v0 — names are stored
|
||||
but not checked.
|
||||
|
||||
**Shape locked in:** the type-checker's index synth path now
|
||||
exposes 3 polymorphic cases via the same `:index` AST — slice,
|
||||
array, map. This is the third place (after binding-groups and
|
||||
control-flow sentinels) where a single AST shape parameterizes
|
||||
over its TY interpretation. Sister-plan diary documents this as
|
||||
the **"shape is the parser, role is the validator"** lemma —
|
||||
emerging consistently across deliverables. [shapes-static-types-
|
||||
bidirectional]
|
||||
- 2026-05-28 — **Phase 7 foundation: generics syntax wired through
|
||||
parser + typer + eval.** New `gp-parse-type-params` consumes the
|
||||
optional `[NAMES CONSTRAINT, ...]` clause after a func name,
|
||||
|
||||
Reference in New Issue
Block a user