Commit Graph

2 Commits

Author SHA1 Message Date
Brummel de674c4d0b Iter 15g-aux — symmetric $u early-return in unify_for_subst
Fix the codegen asymmetry that 15g surfaced. unify_for_subst had an
arg-side-only early-return for $u-prefixed synth wildcards. The
function's prev-binding recursion can swap a $u from arg into param
position when re-unifying a previously-bound type against a fresh
arg. Reduced repro: `length [Left 1, Right 10]` — `a` first binds
to `Either<Int, $u>`, then the recursive unification against
`Either<$u, Int>` lands $u in param-pos[1] and falls through to
the catch-all error.

Fix is three lines: add a symmetric $u early-return for param side.
$u is a synth-only wildcard regardless of which side it ends up on
after the prev-binding swap. Doc comment expanded to record the
origin and justification.

std_either_list_demo refactored: mkleft/mkright workaround helpers
removed; the list is now constructed inline by mixing
(term-ctor std_either.Either Left 1) and (... Right 10) directly.
Same expected output (2, 3, 2, 3); the demo doubles as the 15g-aux
regression fixture.

Tests: 94/94, unchanged. The fix expanded what compiles without
changing observable behaviour for any prior fixture.
2026-05-07 19:59:42 +02:00
Brummel e1587ebdae Iter 15g — std_either_list: first 3-way cross-module stdlib fn
First stdlib fn that imports three other stdlib modules (std_list,
std_either, std_pair) and returns a compound polymorphic ADT tree
(Pair<List<e>, List<a>>). Stresses monomorphisation across nested
parameterised ADTs.

What shipped:
- examples/std_either_list.{ailx,ail.json}: 3 combinators —
  - lefts : forall e a. (List<Either<e, a>>) -> List<e>
  - rights : forall e a. (List<Either<e, a>>) -> List<a>
  - partition_eithers : forall e a. (List<Either<e, a>>)
                        -> Pair<List<e>, List<a>>
  lefts/rights use depth-2 nested Ctor patterns (Cons (Left l) t)
  — exercises 16a's desugar pass at a depth not reached by any
  prior fixture.
- examples/std_either_list_demo.{ailx,ail.json}: drives all three
  combinators on a five-element List<Either<Int, Int>>; expected
  output one per line: 2, 3, 2, 3.
- crates/ail/tests/e2e.rs::std_either_list_demo: e2e count 34 → 35.
- docs/JOURNAL.md: Iter 15g entry.

Compiler bug surfaced (queued as 15g-aux, not fixed):
unify_for_subst in ailang-codegen/src/lib.rs accepts $u wildcards
only on the arg side. Mixing inline (Either Left n) and (Either
Right n) in a list literal lands $u on the param side via the
outer List<a>'s binding and errors. Reduced repro: `length [Left
1, Right 10]`. Demo works around with monomorphic mkleft/mkright
helpers; workaround documented inline. Fix is a one-line symmetric
extension of the early-return.

Tests: 94/94. Stdlib: 5 modules, 27 combinators.
2026-05-07 19:57:06 +02:00