Small empirical iter confirming the 14e tail-call story works
dogfood-practical. New fixture std_list_stress.ailx builds a
1000-element List<Int> via recursive build, folds it with both
fold_left (tail-marked in std_list) and fold_right (constructor-
blocked, unmarked), prints both sums (500500 each).
IR evidence at the monomorphised fold-recursion sites:
fold_left__I_I: musttail call i64 @ail_std_list_fold_left__I_I(...)
fold_right__I_I: plain call i64 @ail_std_list_fold_right__I_I(...)
The tail: true marker on std_list.fold_left's recursive call
survives monomorphisation through the __I_I specialisation.
fold_right correctly emits a plain call (recursive call is
second arg to f, not tail position).
Empirical findings at N=1000:
- fold_left runs in constant stack (musttail).
- fold_right runs in ~1000 frames. No segfault; default 8MB
Linux stack absorbs it comfortably.
- build (recursive, unmarked) likewise fits.
- End-to-end ~40ms wall (build + clang link); program <1ms.
- Boehm GC handles 2 × 1000 Cons allocations without symptom.
Tests 87 -> 88. Cumulative 30 e2e tests. cargo doc 0 warnings.
Cumulative state, post-15c: 2 stdlib modules (std_maybe,
std_list), 14 combinators, cross-module recursive ADTs working,
TCO surviving monomorphisation, GC at 1000-element scale. Four
compiler bugs surfaced + fixed in dogfood since 14a.
Natural pause point. Queue for future iters: 15d (std_either),
15e (std_pair), 16a (nested patterns), 16b (local rec let),
17a (per-fn arena, Decision 9 future-iter). None block further
stdlib work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>