Split Loop

Removes smells
Compare
Symptom
Human

A single loop iterating one collection but doing multiple unrelated jobs — accumulating a sum, finding a minimum, building a derived list, all interwoven in the loop body.

Agent

A single loop body that mixes filter, map, reduce, and side-effect concerns; the agent verifying any change must trace all concerns through the same iteration.

Goal
Human

Each loop does one thing; mixed-purpose loops separate into named single-purpose passes.

Agent

Each loop does one thing; the agent reasons about one concern per loop and can replace each loop independently with a pipeline.

Before the refactoring

let totalSalary = 0;
let youngest = Infinity;
for (const p of people) {
if (p.age < youngest) youngest = p.age;
totalSalary += p.salary;
}

After the refactoring

const totalSalary = people.reduce((s, p) => s + p.salary, 0);
const youngest = Math.min(...people.map(p => p.age));
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure
Human

Each line of the body could touch any of the loop's concerns; reasoning about one purpose requires holding all of them; bugs hide where concerns share an iteration variable.

Agent

The agent's per-line reasoning must account for every concern the loop body addresses; changing one concern risks silent interaction with the others.

Tradeoff
Human

Two loops over the same collection are slower than one — only split when the doubled cost is dwarfed by the readability gain (which it usually is).

Agent

Two loops over the same collection cost more per iteration than one; for hot paths the runtime overhead matters and the agent verifying performance must measure.

Relief
Human

Each loop can then be replaced by a pipeline or extracted by name; bugs concentrate in one purpose at a time.

Agent

Each loop body holds one state machine the agent simulates without interleaving; an edit to one job no longer needs the other job's tokens loaded to predict the loop's output.

Trap
Human

Splitting a loop whose concerns genuinely share state — running total AND previous value, where each iteration depends on the previous — fragments coupled logic into pieces that have to re-derive shared state.

Agent

Splitting loops whose concerns share per-iteration state — accumulator-of-running-difference, look-behind logic — fragments coupled state the agent must now re-derive in each split.