27

Separate Query from Modifier


Goal

Functions either return a value or mutate state, never both — callers can compose them without surprise.

Before the refactoring
function findMiscreant(people) {
  for (const p of people) {
    if (p.isMiscreant) { alert(p); return p; }
  }
}
After the refactoring
function findMiscreant(people) { return people.find(p => p.isMiscreant); }
function alertMiscreant(people) {
  const m = findMiscreant(people);
  if (m) alert(m);
}
Savings

Reasoning about side effects is local; tests target each shape independently.

Note

If the modification and the query truly cannot be separated (e.g. find-and-remove on a queue), the constraint is fundamental — leave the combined operation but document it.