Accumulator Introduction

The centerpiece of this release cluster is accumulator introduction. The optimizer detects recursive patterns like f(n-1) + k (additive) and n * f(n-1) (multiplicative) and rewrites them into zero-overhead loops. Given this LOGOS source:

## To factorial (n: Int) -> Int:
If n is at most 1:
Return 1.
Return n * factorial(n - 1).

The codegen emits:

fn factorial(mut n: i64) -> i64 {
let mut __acc: i64 = 1;
loop {
if n <= 1 {
return __acc * 1;
}
{
let __acc_expr = n;
__acc = __acc * __acc_expr;
let __tce_0 = n - 1;
n = __tce_0;
continue;
}
}
}

The identity element (1 for multiplication, 0 for addition) initializes the accumulator. Each recursive return becomes an accumulator update and a continue. Stack frames are eliminated entirely.

Mutual TCO and Memoization

Mutual tail call optimization handles function pairs like isEven/isOdd that call each other in tail position. The optimizer merges them into a single __mutual_isEven_isOdd function with a __tag: u8 parameter and a loop { match __tag { 0 => { ... }, 1 => { ... } } } dispatch. The original functions become #[inline] wrappers that call the merged function with the appropriate tag.

Automatic memoization targets pure functions with multiple recursive calls. A fixed-point purity analysis identifies side-effect-free functions (no Show, file I/O, CRDT operations, etc.). Pure multi-branch functions like Fibonacci receive a thread_local! RefCell<HashMap> cache — the function checks the cache before executing, stores results after, and drops complexity from O(2^n) to O(n) with zero source changes.

Peephole Patterns and Build Profile

Lower-level optimizations target generated Rust quality:

  • Vec fill: a push loop with constant value becomes vec![val; count]
  • Swap pattern: adjacent-index comparisons with temp-variable swaps become arr.swap(i, j)
  • Copy-type elision: .clone() on Vec/HashMap indexing dropped for Copy types (i64, f64, bool)
  • Direct collection indexing: known Vec/HashMap types use direct indexing instead of trait dispatch
  • HashMap equality: map.get() replaces map[key].clone() in comparisons

Release builds use opt-level = 3, codegen-units = 1, panic = "abort", strip = true, and LTO. Hot paths carry #[inline]; all Showable, LogosContains, and LogosIndex trait impls use #[inline(always)].