Leaky Abstractions Are Holding Us Back
Let's just get right into it, shall we?
What is an abstraction?
Before we can talk about leaky abstractions, and why they are bad, let's define what exactly an abstraction is.
An abstraction is when we take a complicated thing and we make it simpler by generalizing it based on the way we are using or talking about that thing.
We do this all the time. Our brains work by creating abstractions so that we can deal with vast amounts of information.
We don't say “my Dell Inspiron 2676 with 2 GB of RAM and a 512 GB hard drive, serial number 12398ASD.” Instead we say simply “my computer.”
In programming, abstractions let us think at higher levels. We create abstractions when we give a bunch of lines of code that get the username and password out of a textbox and log the user into our system, a name; login. And we use abstractions when we utilize APIs or write to the “file system.”
Without abstractions we'd have a really hard time managing the complexity of any software system. Without abstractions, it would be pretty difficult to write any kind of non-trivial application.
If you want to feel what it is like to program with fewer abstractions, try serving up a web page with assembly code. If you want to feel what it is like to program with almost no abstractions, do the same exercise, but write your code in machine code… 0s and 1s.
How do abstractions “leak?”
This means the details of the lower level concept that are being abstracted away are leaking up through the higher level concept.
Ever get a cryptic error message when an application you are using crashes? That is a leaky abstraction.
“Memory location 00FFE133 could not be written to” is just bad news. It means that in order to understand what is going wrong with your application, you now have to understand the inner workings of the application. Your abstraction has effectively “leaked.”
Abstractions leak whenever you are forced to pull back the curtains and see the gnomes running in hamster wheels spinning the cogs.
Why “leaking” is bad
I'm often surprised when I hear someone say “I like how you didn't hide the details of what is really going on” about some code or some technology.
Not being able to hide the details of what is really going on points to an inability to create the proper abstraction, which in my opinion, should be water tight.
It is not a good thing that we can see what is really going on. No, it is actually a very bad thing, because it forces us to think at the higher level some of the time, but have to switch gears to drop down to the lower level some of the time.
Leaky abstractions prevent us from being able to comfortably drive the kids to school; we have to constantly keep looking in our rear view mirror and checking to see if those rowdy kids who insist on sitting at the back of the bus are causing trouble again.
A good abstraction hides the details so well that we don't ever have to think about them. A good abstraction is like a sturdy step on a ladder, it allows us to build another step above us and climb up it. A leaky abstraction is like a wobbly rotted wood rung; put too much weight on it and you'll fall through—it traps you at the current step—you can't go any higher.
Shouldn't we understand how things really work?
No! Stop already! Enough with the guilt trips and unnecessary burdens. You are defeating the purpose of abstractions and stunting further growth.
You only “need” to know the details if you want or need to know the details.
I know that many people want to know how things really work, myself included for many things, but in many cases I don't need to understand how things really work.
For example, I can buy and use a watch without understanding how the watch works. It really is better that way. I don't need those details floating around in my head. I get no benefit from knowing what is going on inside my watch and frankly, I don't want to know.
When I buy a car, I just want to drive it. I don't want to remember when to rotate tires, check fluids, etc. Waste of my time. I don't want to know how the engine works or anything about it besides I have to put gas in, turn a key, and press a few pedals to make the thing go. I know I could save money servicing my own car, but you know what? I'd rather pay money than have to do it myself. And since that is the case, as long as I can find someone I trust to work on my car, I don't want that abstraction to leak.
The same with machine code and compilers. Yes, it is interesting to understand how memory mapping and CPUs and logic gates work and how my C# code gets compiled into MSIL which is interpreted by the CLR and so forth and so on, until it ends up as electrons operating on registers in my CPU. And I learned about how much of that works, because I was interested, but let's be completely honest here. That abstraction is really good. It is so good and so air-tight, that I don't need to know all of that crap in order to write a web app. If I did, I'd probably find another profession, because my brain would explode every time I tried to write the simplest piece of code.
By the way, if you do want to understand what is happening behind many of those abstractions, I highly recommend Charles Petzold’s book: “Code: The Hidden Language of Computer Hardware and Software”. (This is the kind of book you read for “fun,” not because you need to know this information.)
Leaking abstractions in technology
Too many technologies and frameworks today are leaky, and this is bad– really bad.
Want an example? Whatever happened to ORM (Object Relational Mapping?)
Nothing. Nothing happened. It was invented, oh, like thousands of years ago and while lots of other technologies and frameworks grew up and got jobs and left the nest, ORM is still a fat unemployed balding 30 year old man playing WOW all day in his mum and dad's basement.
Don't get me wrong. I use ORMS; I sometimes like to think I like ORMS. But, I can't use them well because I have to understand SQL and what is going on in my relational databases anyway. What good is that?!
Seriously. This is a completely failed abstraction. The leakiness of it makes it actually more work to learn an ORM framework, because in learning one you must also learn hairy details of SQL and understand what N+1 means and so on. You can't just fire up your ORM and put in the Konami code, you have to blow the cartridge out and fiddle with the reset button half a dozen times. Useless.
I could go on and on with examples of leaky abstractions in technology and how they are holding us back, but I think you get the point by now.
Leaky abstractions are bad. They don't do anything good for us besides require us to know more and add more points where things can go wrong. We've got to seal up these abstractions, if we want to be able to keep climbing the software development ladder. You can't keep building a tower if you have to worry about every single block beneath you. You eventually get to a point where you can't keep it all straight and your tower comes crashing to the floor.
Leaky abstractions and you
So, what can you do about it?
You really have to make a choice. Am I going to hide the details so that no one needs to know about them, or am I going to expose the whole thing? Either make a really good abstraction that doesn't require someone using your code to understand what is going on underneath that abstraction or don't attempt to make an abstraction at all.
It takes more effort to create good abstractions. Sometimes the effort required is orders of magnitude greater. But, if other people are going to use your abstraction, to save the mental burden of understanding what is happening beneath it is going to go a long way in making up for your extra effort.