Carry/Bring Loops: Removed Feature

Carry/bring was an SSA-style loop iteration state mechanism. It was fully implemented across the entire compiler stack (parser, AST, typechecker, drop analysis, IR block parameters, interpreter, AOT/Cranelift), then removed in commit cbc756c2 as experimental complexity that didn't prove necessary.

This topic keeps coming up in design discussions. This document records what it was and why it was removed.

Syntax

// Carry only: iteration state.
loop carry (acc: u32 = @1, i = n)
    if i <= @1
        break
    end if
    continue(acc * i, i - @1)
end loop

// Bring only: exit values.
loop
    set x = x + @1
    if x .> threshold
        break(x)
    end if
end loop bring (found: u32)
ret found

// Combined carry and bring.
loop carry (acc: u32 = @1, i = n)
    if i <= @1
        break(acc)
    end if
    continue(acc * i, i - @1)
end loop bring (result: u32)
ret result

// With while condition.
loop carry (i: u32 = @0) while i .< limit
    set total = total + i
    continue(i + @1)
end loop

Rules

Implementation

Used SSA block parameters (not phi nodes). Loop header block had params for carries; exit block had params for brings. Goto/Branch terminators passed args to target blocks.

Known issues at time of removal:

Why removed

Commit message: "The carry/bring feature was experimental and added complexity without proving necessary."

Plain var/set handles loop iteration state:

var acc: u32 = @1
var i = n
loop
    if i <= @1
        break
    end if
    let new_acc = acc * i
    set i = i - @1
    set acc = new_acc
end loop
ret acc

The var/set version is more verbose but uses no special syntax. The carry/bring mechanism added significant complexity to every compiler phase for a feature that var/set already covers.

Archived documents