There’s a joke in computer science that everything can be solved with another layer of abstraction or indirection. It’s true. In our line of work, tools are essentially good abstractions for the problem we’re solving. Our craft and discipline is built with abstractions, and yet, I find it’s something hard for programmers to grasp.
Why use abstractions in the first place? We build abstractions to make it easier to work on the problem we’re trying to solve, without getting distracted by details from the big picture. We want to be able to drive a car using a an abstraction called a gas pedal, rather than timing the firings of the spark plugs in the engine, which is what actually moves the car forward. This abstraction lets us worry about that “what”–getting from point A to point B–without worrying about the “how”–the specifics of how that occurs.
I think we all know the above logically, but emotionally and in practice, we often disregard the ideas above. Ideally, a programmer not only gets the program to do what it wants, but also produces usable abstractions for other coworkers along the way. Often times we laud the quickest programmers, but I think the best programmers are ones that build usable abstractions for other programmers. The ones that build tools for others to use and increases the productivity of those around them. And yet, I’ve met programmers that didn’t like to build abstractions.
There are some programmers that like to have everything on a single page. . I suspect these are programmers that can hold an inordinate number of things in their head. They can look at all the details of which pistons are firing at which time all at once, and still understand the whole thing. But even this is unsustainable at some point, as there’s no physics capping the upper limit on the size of code bases. In addition, coding, at its core, is a social activity. If you write code that others find hard to follow because you’re mixing the “what” with the “how”, then your code is less useful to others, both to use and to maintain.
There are yet other programmers that fear it makes the code slow. I’ve seen Ruby code written as if it was C code. This is counter productive. Often times you don’t know which part of your code is the slowest until you measure and profile. Often times, your intuition is wrong about which paths get executed the most. There are diminishing returns to make a piece of code faster. If it takes 10 seconds to run, then a 50% reduction in time is great! But if it already takes 10 milliseconds to run, then the extra 5 milliseconds may not be worth it, as there are often many other pieces of code that would take 5 milliseconds or more to run. In addition, a user will not notice 5 ms as much as 5 seconds.
So while not every programmer should build tools for others, I believe it’s something every good programmer should aspire to. However, this is often a difficult skill to learn and get right in practice. It’s not easy to do under the time crunch of deadlines and fire drills. Even if you didn’t have those time pressures, it’s still hard to get right.
Why is it so hard to build useful abstractions? For one, you can often hide the wrong details. And when you hide the wrong details, the abstraction is useless because you need to manipulate the details. On the other hand you can veer too far the other way, by building abstractions that are too flexible, requiring too many new concepts for users to grasp before they’re productive.
The culprit to both problems is that we often don’t understand the problem well enough when we sit down to write. When you don’t yet understand all the different circumstances that you’d use an abstraction, you expose either too much or too little.
There are two ways to combat this. First, you should set out to write the application, and extract the framework or platform for it, rather than setting out to write the platform. I’ve seen some useless web frameworks because they set out to write the framework, rather than be informed by experience writing applications. Second, you should do something akin to sketching. You write the core of what is still unknown about the problem domain then test it. If you’re building a blog engine, you start writing the posting and commenting, not the login. Then refine it as you understand more about the domain.
Make tools for yourself that’s informed by the problems you face when you’re trying to get something done. It’s not a waste of time. It’ll make you sharper as a programmer, and you may get better technical or business ideas as a result. It’ll make you more productive, and you’ll be able to delight others once you learn this skill that requires experience and taste.