diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 7d28a87..f556158 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -1604,7 +1604,14 @@ with a call to a synthesised monomorphic `FnDef`. For each unique After this pass, the IR contains no class machinery — only ordinary monomorphic functions and direct calls. Codegen sees no difference -between a hand-written `show_int` and a synthesised `show@Int`. +between a hand-written `show_int` and a synthesised `show__Int`. + +The separator is `__` rather than `#` or `@` because `#` and `@` +are invalid in LLVM IR global identifiers (the IR verifier rejects +them inside `@ail__` mangled names). `__` is legal in +both LLVM IR and the C ABI used by the runtime glue, and parses +unambiguously into `__` because neither +component contains `__` by project convention. **No runtime dispatch, no dictionary passing.** The monomorphisation pass is the ONLY mechanism for class-method calls. A call that diff --git a/docs/specs/2026-05-09-22-typeclasses.md b/docs/specs/2026-05-09-22-typeclasses.md index e1b9d40..c91c41d 100644 --- a/docs/specs/2026-05-09-22-typeclasses.md +++ b/docs/specs/2026-05-09-22-typeclasses.md @@ -235,3 +235,86 @@ function or class method with any of these names fires `method-name-collision`. The cost is a small lexicon of forbidden names; the benefit is no namespace fragmentation across the Prelude classes. + +## Amendments + +### 2026-05-09 — Iteration split: 22b.4 → 22b.4a + 22b.4b + +Original 22b.4 scope ("Prelude module Show/Eq/Ord on Int/Float/Bool/String, +print rewiring, Form-B parser/printer arms, round-trip filter retired") +splits into two iterations: + +- **22b.4a (this iter):** Form-A parser+printer arms for ClassDef + and InstanceDef; round-trip skip-list retired for `test_22b1_*`, + `test_22b2_*`, `test_22b3_*`. Pure surface plumbing, no codegen + or runtime change. +- **22b.4b (queued):** Prelude module containing `class Show a where + show : (a borrow) -> Str`, `instance Show Int`, the new + `int_to_str` C-runtime primitive, codegen wiring for it, and an + end-to-end `show 42` fixture that prints `42` through the existing + mono pass. + +Substantive rationale: 22b.4a touches one crate (`ailang-surface`) +with no runtime/codegen risk; 22b.4b touches `runtime/`, +`ailang-codegen`, `ailang-check::builtins`, plus a new fixture, with +a different review surface and a different bench-gate exposure. +Bundling them was a brainstorm-time underestimate of the +runtime-side work; running them as separate iterations preserves +the bite-sized cycle the skill system enforces. + +### 2026-05-09 — Form-A vs Form-B terminology fix + +The original 22 spec ("Form-B parser/printer arms for ClassDef +/InstanceDef") and the 22b.1 round-trip-skip-list comment both +loosely call the s-expression projection "Form-B". That is a +terminology error: `crates/ailang-surface` is **Form-A** (the +parseable s-expression). `crates/ailang-prose` is **Form-B** +(human-readable, one-way projection — no parser by design). The +22b.4a arms are Form-A. Form-B printer arms for ClassDef / +InstanceDef are NOT required for the round-trip gate (it is +unparser-side); they are queued as an audit-cycle nicety, not as +a milestone-22 acceptance criterion. + +The skip-list comment that read "the surface (Form-B) parser/printer +arms" was retired alongside the filter (Task 5). + +### 2026-05-09 — Mono-symbol separator: `__` chosen over `#` + +22a's brainstorm recommended `#` for the +mono-symbol naming format with the implementer free to choose. 22b.3 +implemented `__` instead (e.g. `show__Int`, +`eq__Bool`). Reason: `#` is an invalid character in LLVM IR global +identifiers (`@ail_..._foo#Int_clos` is rejected by the LLVM +verifier). `__` is verifier-legal, identifier-legal in C-glue +contexts, and parses unambiguously into method + type surface name +(neither method names nor type surface names contain `__` by +convention). The recommendation in §"Open commitments (22a → 22b +implementer)" is updated to read `__`. + +Hash-suffix form for compound types (`__<8-hex>`) follows +the same separator. + +### 2026-05-09 — Forall-constraints surface arm gap (22b.4a.4.5) + +Surfaced during 22b.4a Task 5: the existing Form-A parser/printer +arms dropped `Type::Forall.constraints` (the field added in 22b.2 to +carry class constraints on polymorphic types). Four `test_22b2_*` +fixtures regressed when the round-trip skip-list was lifted. Fixed +in 22b.4a.4.5 by extending `parse_forall_type` and the `Type::Forall` +arm of `write_type` to handle an optional `(constraints (constraint + )+ )` clause. Round-trip is now bit-stable for every +forall-with-constraints fixture in `examples/`. + +This was not in the original 22b.4 plan because the brainstorm did +not anticipate the gap — the skip-list was thought to mask only the +ClassDef/InstanceDef arms, not the forall-constraints arm too. The +forall-constraints fix is properly part of 22b.4a (cannot retire the +filter without it) and is recorded here for completeness. + +### 2026-05-09 — Acceptance criteria 4 still binding + +Acceptance criterion 4 ("Round-trip filter `test_22b1_*` is removed; +all `examples/*.ail.json` pass round-trip") is satisfied by 22b.4a. +The `test_22b2_*` and `test_22b3_*` filters added subsequently are +also retired here. No further round-trip gate work is required for +22 milestone close.