Yeda AI Tips · #104

Español

Early Returns Kill Nesting, Named Constants Kill Magic Numbers

Two thirty-second fixes make AI-generated code readable. Early returns kill nesting, named constants kill magic numbers. Your assistant loves deep pyramids of nested ifs and unexplained numbers like 3 or 500 — both are classic code smells, both are easy to spot in a diff, and both take under a minute to fix.

Why AI-generated code smells this way

  1. Nested conditionals. The model wraps the happy path inside every validation check, so the real logic ends up four levels deep. Nesting is expensive for readers: SonarSource's Cognitive Complexity metric explicitly adds a penalty per level of nesting, because each level is one more condition you must hold in your head.
  2. Magic numbers. A numeric literal whose meaning is unclear to the reader — retries < 3, sleep(500), if len(name) > 64. The anti-pattern is old enough that warnings about it date back to 1960s COBOL and FORTRAN manuals, and your assistant reproduces it constantly because the training data is full of it.

Neither smell is subtle. You can find both by scanning indentation and scanning for digits — no tooling required.

Fix 1: flip conditions into guard clauses

A guard clause checks a failure condition first and returns immediately, so the main logic never nests. This is Martin Fowler's Replace Nested Conditional with Guard Clauses refactoring, verbatim:

// Before — AI's favorite pyramid
function payAmount(employee) {
  let result;
  if (employee.isSeparated) {
    result = {amount: 0, reason: "SEP"};
  } else {
    if (employee.isRetired) {
      result = {amount: 0, reason: "RET"};
    } else {
      result = someFinalComputation();
    }
  }
  return result;
}

// After — guard clauses, happy path flat
function payAmount(employee) {
  if (employee.isSeparated) return {amount: 0, reason: "SEP"};
  if (employee.isRetired)   return {amount: 0, reason: "RET"};
  return someFinalComputation();
}

Three lines of guards replace two levels of nesting and a mutable result variable. The reader processes each precondition independently instead of tracking scopes, and the function reads top to bottom like a checklist: bail out, bail out, do the work.

Fix 2: pull numbers into named constants

Fowler's Replace Magic Literal (alias: Replace Magic Number with Symbolic Constant) is the mirror move for data:

# Before
if attempt < 3:
    time.sleep(0.5)

# After
MAX_RETRIES = 3
RETRY_BACKOFF_SECONDS = 0.5

if attempt < MAX_RETRIES:
    time.sleep(RETRY_BACKOFF_SECONDS)

The number now explains itself, lives in one place, and shows up in autocomplete the next time you — or your agent — need it. Exceptions are conventional: 0, 1, and loop counters like i < count are self-evident and don't need names.

Rules of thumb

SmellTriggerFixTime
Nesting3+ indent levels in one functionGuard clauses / early return~30s
Magic numberBare literal other than 0/1/loop boundsNamed constant at top of module~30s
Both at onceNested if x > 500:Guard first, then name the 500~60s

Power-user moves

Resources

Building with AI-generated code? Yeda AI designs, audits, and ships production LLM systems.

Talk to us · Read the blog