Every abstraction in programming adds indirection, which creates a readability cost; the key principle for code readability is to reduce indirection as much as possible, using abstractions only when the reusability payoff justifies the readability cost, and to write long, linear functions with proper block scopes and comments rather than breaking code into many small functions.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Write stupid code: no abstraction is "zero cost"Added:
Hey guys, it's your boy Zach.
Uh with another rant by the river.
It's becoming uh Oh my god, those geese are like hissing at that guy.
He's getting too close to them.
Anyway, uh I am uh um Yeah, I am basically going to do a continuation of that video. There's There's a There's another important point to make here.
Um in the Zig versus Rust video, I basically said that there's this rift between uh between these two philosophies.
And it existed long before Zig and Rust, right? The exact same rift existed between C and C++ programmers 20-plus years ago.
Um where the C programmers emphasized readability, keeping the code flat and relatively free of abstraction. And the C++ programmers were much more in favor of aggressively using abstractions.
Um but particularly to gain uh safety.
And uh what I did not do is really specifically explain well, how do you how do you make code readable?
Every Everybody thinks their code is readable. So, it's it's not really that helpful to say, well, I care about readability.
Um so, I actually think that um there's really just one principle you need to follow and that I obsessively follow.
And I'm just going to say cuz I hate it when when someone dangles, you know, teases something and then it takes them a half hour to freaking say it.
I think that most code readability problems can be distilled down to a single thing, which is too much indirection in the code base.
And really that's just another way of saying too much abstraction, because that's what abstractions are.
Abstractions are indirection.
Um abstraction is the opposite of concretion, and concretion means a direct specific thing. So, an abstraction is a is indirection that can describe describe multiple concretions.
The word animal is an abstraction over specific concretions like dog, cat, moose, whatever.
And uh and so it so it it creates indirection to describe multiple concrete things.
It's the same thing in programming.
Um you know, one example of an abstraction is an interface and or a trait in Rust.
I'm not against them, but you any kind of abstraction adds indirection to the code, which means there's always a cost.
There's no such thing as a zero-cost abstraction um unless you're purely thinking of cost in terms of run-time cost. I'll get into that a little bit. It's like a sub-rant I have.
But uh every abstraction adds indirection, which means there is a readability cost because code that is less indirect reads more linearly. It's much easier to read. And so, if you want one principle to obsessively follow, it's reduce indirection in your code base as much as you can.
That doesn't mean never use abstractions.
It means use them carefully and only when you are sure you need it.
Um you know, I don't want to pick on Rust, but this specific example has to do with Rust.
Um so you may know Mitchell Hashimoto, he's the co-founder of HashiCorp. Now he's retired and just writing Zig.
Um he wrote Ghosty.
Well, a while ago I saw him on the Primagen.
I don't know, maybe like a couple years ago.
And uh the Primagen asked him um what did he think about Rust? And what he said and instantly clicked with me.
He he said his main issue was that when he was encountering a large Rust code base that he didn't write, he would he would get into this thing he called trait chasing, where he'll see a trait method being called somewhere and now he's got a spelunk the whole code base looking for the trait implementation so that he can understand what's going on.
Now, I'm not picking on Rust cuz this the same thing happens with any kind of interface-like feature.
Because an interface is indirection.
Think about it. Previously, the code was just calling direct functions.
Then you create an interface and you make the code call the interface methods instead.
So now, instead of me having a specific function I can I can click on and look at, there are multiple possible implementations of that interface and I need to track them down if I want to understand the code. You can't say that's not a readability cost. It it does reduce um it it it adds a burden on the reader over direct function calls.
Not saying that interfaces are bad, but that you need to use them sparingly and only when the payoff is uh is good enough.
Usually, the payoff is you gain reusability. For any abstraction, you gain reusability, you lose readability.
That's essentially always the trade-off.
But, no one ever thinks about it that way.
And you can tell from the use of the term zero-cost abstraction. It's like um Yeah, there may not be run-time cost because Rust traits are resolved statically.
Sure. Sure, there's no run-time cost.
But, using that term reflects something about your way of thinking. It's showing that you only care about run-time cost and that you don't see complexity as a cost. You You don't see um readability problems as a cost.
It is a cost.
Every abstraction has a cost.
It If not a run-time cost, then at least a readability cost. You're adding indirection to your code base.
That is a cost.
Um Now, there's another kind of abstraction.
A much simpler kind. The The humble function.
Functions are an abstraction. People don't really think about it that way, but uh they're a much simpler abstraction.
But, they also add indirection.
Think about it. Previously, you had a block of code that was in line somewhere.
And then you break it out into a smaller function. You've created a little abstraction now. Previously, that code was concretely in one place.
Then you pulled it out, given it a name.
And now you can reuse it. So, you get the same trade-off. You gain reuse, but you lose some readability because now that function that previously read linearly, and now I have got to jump all over the place to read it.
To To understand it.
That is a cost. It's not quite as significant of a cost as interfaces because at least there's only one function definition I need to find.
But it's still a cost.
So, if you want my general belief about code read it readability, aggressively in line your code.
This is the opposite of the advice that we were given um when we started programming. We were always taught uh break code out into small functions.
It's more readable.
And I think that's just total I think it's the exact opposite. Long functions that read linearly are much more readable than breaking code out into lots of tiny functions.
The reason people so often get this wrong is because when they think of a long function, they think of a single level of scope with no comments or documentation. Well, yeah, if you break that into smaller functions, you've you've gained comments because the the function name serves as a comment.
And uh you've you've also um nicely scoped locals because uh they can't escape the end of the function.
It turns out you don't need to break code into functions to do that. Right?
You can have one long function that creates block scopes when necessary, so that locals do not leak past when they are necessary or what when they are needed.
And of course, you can add comments um as needed at the top of each block scope. And if you look at my code, this is all I do.
I just have tons of these long-ass functions where the blocks you know, everything is scoped properly in into smaller block scopes, and I have comments describing what's going on.
I think as long as you do that, the code is more readable with long monolithic functions.
It reads linearly, and it prevents premature code reuse, because that can also um lead to lead to uh readability problems.
Whether you're talking about functions or interfaces or any other abstraction, there's always this same exact trade-off. You're gaining reusability, you're losing some readability because now I have to jump around more to uh to understand your code.
This is the point I made in that video where like a typical C function is is nicely linear and uh you see everything.
And then when you rewrite that in a style more typical of a language like C++ or Rust, um you get you you suddenly have a lot more indirection, you know, you're you're putting the cleanup code in destructors.
Um maybe you're you're making use of other language features like traits.
It typically will lead to more indirection. And in my view, that means less readable.
Doesn't mean it's always bad, but if you can't even articulate that this is a trade-off, if you think that it's zero cost and that there's no downside, you're going to overuse it. And people do all the time.
You you confront one of these codebases and it's just uh just swimming in abstractions everywhere.
And you got to go through layers and layers before you get to the concrete code at all, the code that actually does something.
Whereas in a language like C or Zig, it the code is what I call flat. It's it's a lot more flat because these languages don't really provide many tools for abstraction out of the box. There's a lot more friction. You have to create the abstractions manually.
And so you naturally use them less. You write code that is much more direct.
Abstractions are good if that code reuse payoff is uh is enough to justify the the readability cost.
Um but you have to be able to at least articulate that. And almost nobody can.
Even senior developers, they just can't articulate that there's even a downside to using all these abstractions.
I think a lot of people are permanently stuck in this sort of intermediate level of programming.
Um I'm a big fan of uh what I call stupid code. And and stupid code to me is exactly what I'm describing. It's code that is flat and relatively unadorned and unobstract.
Unobstracted.
Um What's funny is when we all started programming, this is the code we wrote.
Right? Because we didn't we didn't know how to use an interface yet.
And uh breaking code out into functions was was annoying when we we were beginners. So we would just write these long-ass functions that um in in retrospect, it's kind of like what I reverted to.
But once you get to the intermediate level, you learn about all of these abstractions.
And uh you you're you're you're fooled into thinking this is what real programmers do. So you overuse them. And you can immediately tell when code was written by someone like this.
You know, they're just totally over overusing um abstractions, particularly interfaces.
And uh just creating layers and layers that aren't even necessary.
You find you look at their code and they like have an interface with one implementation. You're like, why did you even make that interface?
Oh, just because uh I thought maybe I'll need to implement it differently later.
Create a different implementation.
That's called a premature abstraction and it's it's it's uh it's very common for someone at that level.
And this is where most people stay their entire career, you know? It's like the bell curve meme.
Most people are are stuck in that middle part of the bell curve.
And eventually some people get past that point.
And they learn to use abstractions really sparingly. So they essentially revert back to writing the stupid code that they wrote as a beginner. Except now, of course, they have the knowledge to use abstraction sparingly when it actually helps.
I've noticed, by the way, that um um the sort of programmers that tend to overuse abstractions and over-architect, they're always the sort of people who are kind of insecure. You know what I'm talking about? Like we've all sort of worked with that person.
If you haven't, then you might be that person.
You know, the the sort of programmer who just can't really handle criticism and always tries to puff himself up and uh um that sort of person cannot write stupid code. He has to overuse abstractions and uh write code that uh is prematurely reusable.
Because he thinks that's what real programmers do. And if you write stupid code, he'll get judged for it. So that sort of insecurity prevents you from uh writing code that is, as I call it, stupid.
Also, an insecure person cannot self be self-deprecating.
So, he would never call his code stupid.
That's another reason I like to use that term.
Um We've all worked with someone like that.
And I think in order to grow as a programmer, you have to be willing to criticize yourself a bit.
And you have to be willing to write code that other people think is stupid.
Um and that's what I strive to do all the time.
Just write long ass functions, make it linear, and very sparingly use abstractions.
That to me is the essence of code readability.
So, I hope you agree.
If not, then screw you.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
🚀 BCS613C Compiler Design | Module 1 to 5 Schema Evaluation 🔥 | VTU 6th Sem 💯 #VTU #bcs613c #exam
Pranavaa-y4y
104 views•2026-06-02











