Files
AILang/docs/journals/2026-05-13-iter-24.2.md
T
Brummel 3286117605 iter 24.2: class Show + 4 primitive instances + 22b TShow migration
Ships class Show a where show : (a borrow) -> Str in the prelude
plus primitive Show Int / Bool / Str / Float instances. Each
instance body is a single-application lambda invoking the
corresponding runtime primitive (int_to_str, bool_to_str,
str_clone, float_to_str) — first prelude instance bodies to call
runtime primitives directly. Float is included in Show (unlike
Eq/Ord) because textual representation is well-defined modulo the
NaN-spelling caveat at DESIGN.md §Float semantics.

The 22b typeclass test corpus is migrated preemptively: 21 fixture
files and 6 consumer files (typeclass_22b{2,3}.rs +
hash.rs ct4 pin + workspace.rs iter22b1 tests + the
instance_present.prose.txt snapshot) rename class Show / show
to class TShow / tshow, analogous to the existing TEq/TOrd
convention. Migration runs before the prelude additions so the
workspace stays green throughout.

Three new tests pin the post-mono shape: show_mono_synthesis.rs
(existence of show__Int/Bool/Str/Float as Def::Fn entries in the
prelude post-mono module), show_dispatch_pin.rs (bare show and
tshow both Step-2 singletons workspace-globally),
mono_hash_stability.rs::primitive_show_mono_symbol_hashes_stay_bit_identical
(body hashes pinned for the 4 new mono symbols).

DESIGN.md §Prelude (built-in) classes drops Show from the
deferred-features list and appends a milestone-24 paragraph
naming the class signature + the 4 instances + the body shape.
print rewire stays deferred to iter 24.3.

Tests: 552 passed (was 548 + 4 new). bench/compile_check +
bench/cross_lang exit 0. bench/check exits 1 on the recurring
noise envelope per the conservative-call lineage.
2026-05-13 03:31:40 +02:00

190 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iter 24.2 — Show class + 4 primitive instances + 22b TShow/tshow migration
**Date:** 2026-05-13
**Started from:** 64cea0e
**Status:** DONE
**Tasks completed:** 8 of 8
## Summary
Ships `class Show a where show : (a borrow) -> Str` in
`examples/prelude.ail.json` alongside primitive instances `Show Int`,
`Show Bool`, `Show Str`, `Show Float`. Each instance body is a
single-application lambda invoking the corresponding runtime primitive
(`int_to_str`, `bool_to_str`, `str_clone`, `float_to_str`) — first
prelude instance bodies to call runtime primitives directly
(prior Eq/Ord bodies used operator + codegen intercept). The 22b
typeclass test corpus migrates `class Show` / `show`
`class TShow` / `tshow` preemptively (Tasks 12 before Task 3 lands
`prelude.Show`) so the workspace stays green throughout. Three new
tests pin the post-mono shape: mono-synthesis existence
(`show_mono_synthesis.rs`), dispatch singleton (`show_dispatch_pin.rs`
× 2 cases), and body-hash stability (`mono_hash_stability.rs::primitive_show_mono_symbol_hashes_stay_bit_identical`).
DESIGN.md §"Prelude (built-in) classes" gains a milestone-24 paragraph
naming Show + instances + the Float caveat. `print`-rewire stays
deferred to iter 24.3.
## Per-task notes
- iter 24.2.1: Renamed `"Show"`/`"show"``"TShow"`/`"tshow"` across 21
`test_22b*_*.ail.json` fixture files; cross-module qualifier forms
(`"<modname>.Show"``"<modname>.TShow"`) handled by regex in 3
fixtures (`test_22b1_dup_a`, `test_22b1_dup_b`,
`test_22b1_orphan_third`). False-positive scan empty; fixture
parse round-trip green.
- iter 24.2.2: Renamed literals in `crates/ail/tests/typeclass_22b{2,3}.rs`
(`"Show"``"TShow"`, `"show"``"tshow"`, `show__T``tshow__T`),
including comment-prose forms (`` `Show` `` → `` `TShow` ``,
`class Show` → `class TShow`, etc.) and one assertion-message string
("exactly one show__Int across the workspace" → "tshow__Int...").
Plan undercount surfaced: the rename touches more than the 2 named
test files — see Concerns below.
- iter 24.2.3: Inserted 5 new top-level defs into `examples/prelude.ail.json`
immediately before `fn ne` (line 223 pre-edit). The `instance Show Str`
body invokes `str_clone` as `Term::Var` — first prelude instance body
to do so. Round-trip green; `primitive_eq_ord_mono_symbol_hashes_stay_bit_identical`
stays green (Eq/Ord hashes unaffected by Show defs).
- iter 24.2.4: New fixture `examples/show_mono_pin_smoke.ail.json`
exercises `show 42`, `show true`, `show "x"`, `show 1.5` in a
let-chain ending in `io/print_str s1`. New test
`crates/ail/tests/show_mono_synthesis.rs::primitive_show_mono_symbols_synthesise`
asserts `show__Int`/`show__Bool`/`show__Str`/`show__Float` materialise
as `Def::Fn` entries in the `prelude` post-mono module. `str_clone`
reachability in instance-lambda position verified implicitly:
`show__Str` materialises, which means the lambda body's `Term::Var
"str_clone"` resolved against the checker's builtin table during
typecheck.
- iter 24.2.5: New pin test `crates/ailang-check/tests/show_dispatch_pin.rs`
asserts `env.method_to_candidate_classes["show"] == {"prelude.Show"}`
(singleton) and `env.method_to_candidate_classes["tshow"] == {"*.TShow"}`
(singleton). API spelled `build_check_env(&ws)` not `Env::from_workspace`
(plan's placeholder name). 2/2 cases pass first-shot.
- iter 24.2.6: Extended `crates/ail/tests/mono_hash_stability.rs` with
a second test function `primitive_show_mono_symbol_hashes_stay_bit_identical`
loading `show_mono_pin_smoke.ail.json` (kept separate from the
Eq/Ord fixture to avoid coupling). Hashes captured first-run:
`show__Int 891eaebe64b3180d`, `show__Bool 1bdb621494e50607`,
`show__Str 3f1d57c90ddce081`, `show__Float 5ab0bdd40b9f8b8f`.
- iter 24.2.7: DESIGN.md §"Prelude (built-in) classes" amended:
milestone-23 paragraph drops "Show" from the deferred list and notes
Show ships in milestone 24; new milestone-24 paragraph names class
signature, instance set (including Float), body shape (single-app
lambda invoking runtime primitive), and the iter-24.3 carry-forward
for `print`-rewire.
- iter 24.2.8: Workspace tests 552 passed / 0 failed
(was 548 pre-iter, +4 new: 1 `show_mono_synthesis` + 2 `show_dispatch_pin`
+ 1 hash-stability). `bench/compile_check.py` exit 0 (24/24 stable).
`bench/cross_lang.py` exit 0 (25/25 stable). `bench/check.py` exit 1
with 2 noise-class metrics (`bench_list_sum.bump_s` +11.71% — 4th
consecutive sighting per `audit-mq` / `mq.tidy` lineage;
`latency.implicit_at_rc.max_us` +145.55% — 7th consecutive sighting of
the documented noise envelope, metric-identity-migrating across runs).
Baseline pristine per the conservative-call convention.
## Concerns
- **Plan undercount on 22b migration scope.** The plan's "2 Rust test
files" carrier (typeclass_22b{2,3}.rs) missed 4 additional consumer
sites that hardcode the renamed literals: (a)
`crates/ailang-core/src/hash.rs` ct4 canonical-form hash pin (2
entries); (b) `crates/ailang-core/src/workspace.rs` 3 in-crate iter22b1
tests; (c) `crates/ailang-prose/tests/snapshot.rs` (1 snapshot file at
`examples/test_22b2_instance_present.prose.txt`); (d) one
`mono_symbol_compound_type_uses_hash_suffix` assertion in typeclass_22b3.rs
that called `mono_symbol("tshow", ...)` (post my batch rename) but
still asserted `name.starts_with("show__")`. All fixed inline per the
precedent of mq.1 / mq.3 "Plan defects fixed inline" — fixture parse
was the only "green" pre-iter signal the plan's Step 3/4 anchored on,
which masked the broader downstream consumer surface. Suggested
Boss-side reaction: future migration plans run an upfront
`grep -rln '"<rename target>"' crates/` to enumerate the full
consumer set before committing to a per-file enumeration.
- **`str_clone` reachability is implicit.** Pre-flight note 3 flagged
this as needing first-round-trip verification; verification is
implicit in `primitive_show_mono_symbols_synthesise` passing
(mono of `show 42 / true / "x" / 1.5` requires the four `show__T`
bodies to typecheck, including the `str_clone` call in `show__Str`).
No explicit isolated unit test for `str_clone`-in-lambda was added
because the integration pin is strictly stronger; consider an
isolated unit pin only if a future regression makes the integration
test slow to bisect.
- **Hash-stability pin uses a separate fixture, not the existing
`mono_hash_pin_smoke.ail.json`.** Plan Task 6 offered both options;
the separate-fixture path was chosen because `show_mono_pin_smoke.ail.json`
already existed (minted in Task 4) and reusing it kept the Eq/Ord
pin structurally isolated. Both fixtures live side-by-side; the
second test function in `mono_hash_stability.rs` mirrors the first
byte-for-byte modulo the fixture path and pin table.
- **`bench/check.py` exit 1 is the documented recurring noise envelope.**
`latency.implicit_at_rc.*` max-tail metric has been migrating
between runs since `audit-cma` (2026-05-12) — 7th consecutive
observation; `bench_list_sum.bump_s` is the 4th since `audit-mq`.
Plan Task 8 Step 4 explicitly anticipates "1-3 regressed metrics
ratify-without-attribution per conservative-call convention"; this
iter follows that. The baseline stays pristine.
## Known debt
- **iter 24.3 still pending.** Carries `print : forall a. Show a => a -> () !IO`
rewire to route through `show` + `io/print_str`. Spec at
`docs/specs/2026-05-13-24-show-print.md`. 24.2 is structurally
complete; 24.3 is operationally distinct.
- **mq1 cross-module fixtures unmigrated by design.**
`examples/mq1_xmod_constraint_class.ail.json` and `..._dep.ail.json`
reference `mq1_xmod_constraint_class_dep.Show` (cross-module, fully
qualified) and ship zero `show` call sites; no dispatch ambiguity
arises once `prelude.Show` lands. They stay as-is per the plan's
pre-flight ratification.
- **mq3 fixtures deliberately retain two-Show shapes.**
`examples/mq3_two_show_*` fixtures test the multi-class dispatch
scenarios (ambiguity + qualifier resolution) and stay unchanged in
24.2 by design.
## Files touched
**Created (3):**
- `crates/ail/tests/show_mono_synthesis.rs`
- `crates/ailang-check/tests/show_dispatch_pin.rs`
- `examples/show_mono_pin_smoke.ail.json`
**Modified (29):**
Prelude + DESIGN:
- `examples/prelude.ail.json` (+5 defs)
- `docs/DESIGN.md` (§"Prelude (built-in) classes" amendment)
22b fixture migration (21 files):
- `examples/test_22b1_dup_a.ail.json`
- `examples/test_22b1_dup_b.ail.json`
- `examples/test_22b1_dup_classmod.ail.json`
- `examples/test_22b1_dup_same_module.ail.json`
- `examples/test_22b1_orphan_class.ail.json`
- `examples/test_22b1_orphan_third.ail.json`
- `examples/test_22b1_orphan_third_classmod.ail.json`
- `examples/test_22b2_class_method_lookup.ail.json`
- `examples/test_22b2_constraint_declared.ail.json`
- `examples/test_22b2_instance_present.ail.json`
- `examples/test_22b2_missing_constraint.ail.json`
- `examples/test_22b2_no_instance.ail.json`
- `examples/test_22b2_two_fns_missing_constraint.ail.json`
- `examples/test_22b2_xmod_classmod.ail.json`
- `examples/test_22b2_xmod_classmod_noinst.ail.json`
- `examples/test_22b2_xmod_instance_present.ail.json`
- `examples/test_22b2_xmod_missing_constraint.ail.json`
- `examples/test_22b2_xmod_no_instance.ail.json`
- `examples/test_22b3_dup_call_sites.ail.json`
- `examples/test_22b3_no_call_sites.ail.json`
- `examples/test_22b3_shadow_class_method.ail.json`
22b consumer-test migration (5 source files + 1 snapshot):
- `crates/ail/tests/typeclass_22b2.rs`
- `crates/ail/tests/typeclass_22b3.rs`
- `crates/ailang-core/src/hash.rs` (ct4 hash pin)
- `crates/ailang-core/src/workspace.rs` (3 iter22b1 tests)
- `crates/ail/tests/mono_hash_stability.rs` (new show test fn)
- `examples/test_22b2_instance_present.prose.txt` (snapshot accept)
## Stats
`bench/orchestrator-stats/2026-05-13-iter-24.2.json`