design: 22a — Decision 11 typeclasses (Haskell-lite, monomorphised, coherent)

This commit is contained in:
2026-05-09 12:16:48 +02:00
parent 30e9b117cb
commit f6cb900082
2 changed files with 442 additions and 0 deletions
+130
View File
@@ -10865,3 +10865,133 @@ directly: DESIGN.md typeclass section, instantiation strategy,
schema nodes for `class` and `instance`, naming convention for
monomorphised functions. Implementer iter (22b) follows after
22a's design lands and is reviewed.
## 2026-05-09 — 22a: typeclass design
Trigger: 22a is the typeclass design iter queued in the previous
JOURNAL entry. Per CLAUDE.md, design iters are orchestrator work
done directly. This entry records the decisions and the reasoning;
the canonical specification lives in `docs/DESIGN.md` as Decision 11.
The Feature-acceptance criterion (codified earlier the same day)
was applied as the primary gate. Each of the five committed
semantic axes traces to a single question: "would an LLM author
unprompted produce code that uses this mechanism, AND does the
mechanism measurably remove redundancy or improve correctness?"
Where the answer was no, the mechanism was rejected.
### Five committed axes
1. **Haskell-lite scope** (multi-method, single-param, optional
defaults, single-superclass). Multi-param classes were rejected
because LLM authors do not produce them unprompted, and because
they would require functional dependencies for tractable
resolution. Full Haskell scope (assoc types, GADTs-style
constraints) was rejected on the same grounds.
2. **Constraints in signatures: explicit and mandatory.** Constraint
inference was rejected for the same reason mandatory mode
annotations are mandatory (Decision 10): explicit annotation
makes every commitment visible at the function boundary, so
reading a signature requires no body-level reasoning. The "alles
sichtbar" line of the project is preserved at this layer.
3. **Resolution: orphan-free coherence.** Modeled on Rust's coherence
rule rather than Haskell's orphan-with-warning. The hard rule
makes registry resolution unambiguous by construction; no
`AmbiguousInstance` diagnostic exists. The trade — reduced
flexibility for third-party instance authors — is acceptable
because AILang's authoring surface is a single workspace, not
an open package ecosystem.
4. **Defaults via explicit `default` keyword.** Haskell's
convention of mixing default and required methods in the class
body without syntactic distinction was rejected on visibility
grounds. The `default` keyword makes "what must this instance
implement" answerable from the class header alone. Same line
as axis 2.
5. **Class-parameter kind: `*` only.** Higher-kinded class params
were rejected because the abstraction they enable (`Functor`,
`Monad`, `Applicative`) is not what an LLM author produces
unprompted. The natural LLM pattern is `List.map`, `Tree.map`,
`Option.map` as separate functions per type, which
monomorphisation handles directly without class machinery. The
kind-`*` restriction also removes the implementation cost of
higher-kinded constraint resolution.
### Prelude scope
Three classes ship in the 22b Prelude: `Show`, `Eq`, `Ord`, with
instances for the four primitive types (`Int`, `Float`, `Bool`,
`String`). `Ord` declares `Eq` as superclass.
`print x` is rewired through `Show.show` at codegen — the one
operator-routing change in 22b.
`==`, `<`, `<=`, `>`, `>=` stay primitive operators. Routing them
through `Eq`/`Ord` would require migrating every existing fixture
and would risk firing the bench gate during a feature iter.
Operator routing is deliberately deferred to a later iter, gated
on bench-stability.
`Num` is NOT in the Prelude. Arithmetic operators stay primitive
and per-type. The LLM-natural pattern of distinct `Int` and
`Float` arithmetic is preserved.
### What 22a does not commit to
- The exact textual form of monomorphised-symbol names (e.g.
`show@Int` vs. `show#Int` vs. a hash-suffixed scheme). Naming
is deterministic from `(method, type-hash)`; the textual form
is fixed in 22b alongside the existing mangling scheme
(DESIGN.md §"Mangling scheme").
- The Form-B (prose) projection of `ClassDef` and `InstanceDef`.
Prose-projector arms for the new nodes are 22b scope.
- Mode-annotation defaults for class methods. Class method
signatures are full FnSigs and carry mode annotations per
Decision 10; conventions (likely `borrow` for read-only methods
like `show`, `eq`, `lt`) settle in 22b.
- Auto-derivation of instances. `deriving` is a future-iter option,
gated on Feature-acceptance at proposal time.
### Why this iter is design-only
Per CLAUDE.md and the previous JOURNAL queue entry, 22a is design.
No Rust crates change in this iter; no schema-floor commit; no
bench corpus change. The iter ships a single edit to
`docs/DESIGN.md` (Decision 11 added between Decision 10 and the
Mangling-scheme section) and this JOURNAL entry. The schema and
implementation land in 22b.
### Test state
288 / 0 / 3, unchanged. Documentation-only.
### Bench gates
Not re-run. No runtime, codegen, or check-time path is touched.
### JOURNAL queue (updated)
- **22b — typeclass implementer.** Schema floor for `ClassDef`,
`InstanceDef`, `FnDef.type.constraints`. Workspace-load
registry build with the three coherence/uniqueness/completeness
checks. Class-schema validation (`KindMismatch`,
`InvalidSuperclassParam`, `ConstraintReferencesUnboundTypeVar`).
Typecheck arms for `MissingConstraint` and `NoInstance`.
Monomorphisation pass + naming convention. Prelude module with
`Show`/`Eq`/`Ord` and the four primitive instances. `print`
rewiring through `Show.show`. End-to-end fixture exercising
the full path. Bench gate at close.
- **22c — typeclass corpus expansion (deferred).** User-defined
classes/instances exercised by an example beyond the Prelude.
Optional `deriving` shorthand if Feature-acceptance gate passes.
- **Operator routing through Eq/Ord (deferred, no commitment).**
Migrating `==`, `<`, etc. to class methods. Big-bang fixture
refactor; gated on bench-stability and on a clear LLM-author
benefit ("less ceremony" alone is not a benefit; needs a
redundancy-removal claim).
- **21'h, latency methodology, FnDef::synthetic, Boehm full
retirement, closure-pair slab/pool, deferred richer integration
paths.** Unchanged from 21'g.