diff --git a/docs/JOURNAL.md b/docs/JOURNAL.md index ffab266..40cfb9b 100644 --- a/docs/JOURNAL.md +++ b/docs/JOURNAL.md @@ -12272,3 +12272,96 @@ Carried-debt status (after this iter): - ✅ Lib.rs gap-related sites at lib.rs:1266 / 1853-1856 / 1978 / 2314-2316 — audit confirmed defensive (no action needed; see `2026-05-10 — Audit: mono-pass env-seeding gaps`). + +## 2026-05-10 — Iteration 22-tidy.6: Form-B prose printer arms for ClassDef + InstanceDef + +Closing the third (and final gating) milestone-22 carried-debt +item: `crates/ailang-prose` previously rendered `Def::Class` / +`Def::Instance` as a one-line placeholder +(`// (class Foo a) -- full Form-B projection deferred (post-22)`). +This iteration replaces the placeholder with a full Rust-flavoured +projection covering class header, optional `extends `, +methods (signature plus optional `default { ... }` body), and +instance header + method bodies. + +`write_fn_def` was extended in the same iter to render forall +class constraints (`forall where Ord a`) so a class-constrained +fn signature survives the projection without semantic loss — a +prerequisite for the superclass snapshot to be useful. + +Three new snapshot fixtures pin every branch of the new render: + +- `examples/test_22b3_default_e2e.prose.txt` — class-with-default + + instance-with-no-method-overrides (no superclass, default Some). +- `examples/test_22b2_instance_present.prose.txt` — class-with-abstract + method + instance-with-method-override (default None, instance + methods non-empty). +- `examples/test_22b2_constraint_declared_via_superclass.prose.txt` + — class-with-superclass + class-constrained fn (extends Some, + forall constraints non-empty). + +Tasks (commit subjects): + +- 22-tidy.6.1: write_class_def + write_instance_def — full Form-B projection +- 22-tidy.6.1 fixup: cover abstract-method + instance-override branches; doc + fallback comments +- 22-tidy.6.2: write_fn_def renders forall class constraints + +Acceptance: 3 RED-first snapshot tests then GREEN; full workspace +test sweep green; bench gates 0/0/0; the four pre-existing prose +snapshots (rc_own_param_drop, rc_match_arm_partial_drop_leak, +rc_app_let_partial_drop_leak, bench_list_sum) stay green +(unaffected — none contain class/instance). The placeholder text +and comment are gone from `crates/ailang-prose/src/lib.rs` +(grep confirms zero hits for "full Form-B projection deferred"). + +Mid-iter design notes: + +- Class methods render with synthesised parameter slot names + (`x`, `x1`, `x2`, ...) because the AST stores method types + but no parameter names. Inline comment in `write_class_method` + records the rationale. +- Class-method `default` bodies render as their underlying AST + shape, which in practice is `Term::Lam` (the parser wraps the + surface `default` body as a closure). So `default { |x: a| -> Int + { 99 } }` is the faithful render — the closure form is the AST, + not the renderer wrapping it. +- Instance methods render as `fn { }` without a + signature. The signature is recoverable from the class + declaration via `InstanceDef.class` lookup + (typecheck-context-dependent substitution of `class.method.ty` + with `class.param -> instance.type_`). Per the prose policy + ("deliberately lossy where the LLM can re-derive the dropped + machinery from typecheck context"), this is the correct + projection — the class def is the authoritative signature + source. +- Plan's Step 4 prescribed adding `Constraint` to the + `use ailang_core::ast::{...}` line, but field access through + `c.class` / `&c.type_` does not require naming the type; + implementer correctly omitted the import to avoid an + `unused_imports` warning. + +Carried-debt status (after this iter, milestone 22 fully closed): + +- ✅ Primitive-name-set consolidation (closed 22-tidy.4). +- ✅ Strict duplicate-clause detection in fn/const/data + (closed 22-tidy.5). +- ✅ Form-B (prose) printer arms for ClassDef / InstanceDef + (closed this iter). +- ✅ Lib.rs gap-related sites at lib.rs:1266 / 1853-1856 / 1978 / + 2314-2316 — audit confirmed defensive (no action needed). + +Milestone 22 carried debt is now empty. Next milestone targets +(orchestrator's call): post-22 Prelude (gated on user-author +demand for primitive `Show`/`Eq`/`Ord`), operator routing through +`Eq`/`Ord` (gated on bench re-baselining), or the +`types/ctor_index` overlay shape question queued from +`2026-05-10 — Audit close: env-construction unify`. + +Out-of-scope observation (not new debt — quality-review nit +surfaced during Task 2): `write_type`'s `Type::Forall` arm +still silently drops constraints in inline-type rendering +(`crates/ailang-prose/src/lib.rs` `write_type` Type::Forall arm). +The inline path is unreachable for the surface forms emitted by +the parser today (forall only appears at fn-signature top level), +so the gap is dormant. If a future feature carries a forall in +inline position with constraints, this is the place to extend.