There's a persistent belief that readable code means short code. Fewer lines, fewer abstractions, fewer concepts. But readability isn't about minimizing — it's about making intent obvious.

The False Economy of "Simple"

Consider this:

$users = array_filter($users, fn($u) => $u->isActive() && $u->hasRole('admin'));
$emails = array_map(fn($u) => $u->email(), $users);

Two lines. Compact. But what does this code want? You have to simulate it in your head.

Now compare:

$admins = $this->activeAdmins($users);
$emails = $this->emailAddresses($admins);

More code overall (those methods exist somewhere), but the call site reads like a sentence. The intent is front and center.

Readability Is About the Reader

The question isn't "how few lines can I write?" — it's "how fast can the next person understand what this does and why?"

Sometimes that means extracting a method. Sometimes it means not extracting one — because the indirection costs more than the duplication saves.

Named Constructors Over Comments

// Bad: comment explains what the code doesn't
$range = new DateRange($start, $end, true); // true = inclusive

// Good: the code explains itself
$range = DateRange::inclusive($start, $end);

The named constructor carries the intent. The boolean parameter with a comment is a readability tax on every future reader.

When Complexity Serves Clarity

A well-placed abstraction isn't added complexity — it's transferred complexity. You're moving it from the reader's head into a named concept they can reason about.

The trick is knowing when the abstraction earns its keep. A good heuristic: if you need a comment to explain what (not why), the code isn't readable enough yet.

The Guideline

Optimize for the reader, not the writer. The reader has less context, less time, and more code to get through.