Code You Don't Have to Read Twice
Why functional programming is worth learning even without proving the math yourself, and what it actually means for code to be easier to trust.
You trust that 1 + 1 = 2 without ever proving it. There's a real, formal proof for it, and it's genuinely hard. You've never needed to see it.
That's the whole reason functional programming is worth learning, even if the math behind it stays a mystery to you forever. A handful of techniques in this series carry that same kind of guarantee. You won't need to prove them. You just need to use them correctly, the same way you use addition.
The Best Code Is the Code You Didn't Have to Read
Compare that trust to how most debugging actually goes: write some code, run it, hope. It fails. Change something. Run it again. That fumbling isn't a personal failing, it's what happens whenever you only partially trust the code in front of you.
Here's the sharpest way to say what this series is chasing: the best code in a codebase is the code you never had to read carefully in the first place.
Picture ten thousand lines split into two buckets. Ninety-nine hundred behave so predictably you stop double-checking them. The other hundred are the real business logic, the part actually worth your attention.
A bug is far easier to find when only a hundred lines could be hiding it, not ten thousand.
This series gives that split a real name: surface area, how much of your code you have to hold in your head to trust one line.
Shrinking it is most of what functional programming is for, and it's exactly what to look for the next time you're reviewing someone else's code: not just whether a function works, but how much of the file you had to hold in your head to believe it does.
What "Easier to Read" Actually Means
Say you need to add up the price of everything in a shopping cart. Most people, regardless of experience, picture almost the same code:
function cartTotal(items) {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
return total;
}This works. It's also imperative: code that spells out how to do something, one step at a time. To understand what it does, you can't just glance at it, you have to run it in your head: start total at zero, add each price, keep going until the loop ends.
That mental replay is the real cost. Computers execute steps quickly and perfectly. Brains don't. Code that forces a reader to simulate execution just to understand its purpose is asking them to do the one thing they're worst at.
Compare that to a declarative version, code that states what you want instead of narrating every step:
function cartTotal(items) {
return items.reduce((total, item) => total + item.price, 0);
}You don't have to trace an index or an accumulator by hand. reduce is doing the same looping underneath, but the code you're reading only states the outcome: fold this list down into one total. This series comes back to reduce properly once it covers list operations in depth. For now, the shape is the point, not the method name.
It's a Spectrum, Not a Switch
Nothing here means a for loop is always wrong. Imperative and declarative aren't two boxes, they're two ends of the same line.
Someone used to writing raw loops sees .reduce() and calls it declarative. Someone used to functional code all day sees that exact same .reduce() and might call it imperative, compared to something even higher-level. Where a piece of code sits on that line depends on what you're comparing it to.
What matters isn't hitting some perfect declarative score. It's noticing, each time, whether you're making the reader simulate steps the code could have just stated as an outcome instead.
The Same Idea Fixes Bad Code Comments
This shows up in comments too:
i++; // increment iThat comment describes how, and the code already says that. It adds nothing. A comment earns its place by explaining why, the part the code can't say on its own. Why increment by one and not two? That's worth writing down. Restating a line in English isn't.
The clearest sign code needs a comment at all is that it couldn't state its own purpose declaratively. The better fix, when you can manage it, is writing code that doesn't need the comment.
One Honest Warning
The first few functional techniques you try will probably make your code feel less readable for a while, not more. That's normal, and it happens to nearly everyone learning this.
Push through the part where it feels worse, and it does turn a corner.
Every technique the rest of this series covers, purity, composition, immutability, is really this same move applied in a different spot: replace a paragraph of "first do this, then do that" with one expression that states the outcome. The next question worth answering is what actually counts as a function in the first place, and it turns out that bar is higher than most code clears.
Keep reading