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

9.8 KiB
Raw Blame History

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 / showclass 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__Ttshow__T), including comment-prose forms (`Show``TShow`, class Showclass 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