Wednesday, June 6, 2012

Code Matters

“Programs must be written for people to read, and only incidentally for machines to execute”
- Abelson & Sussman, Structure and Interpretation of Computer Programs

I want to write about software development. More specifically, I want to write about writing source code.
Many people write code. Sadly, many of them do it the wrong way. What’s even worse is how many of them, and their respective employers, overlook it, or don’t care, or think it doesn’t matter.
At this point people tend to think: this is just software, man, video games and music players. Completely unimportant stuff. In a world afflicted by things like hunger, wars, disease and politicians, does something like sub-optimal source code even matter, in the grand scheme of things?
Yes it does.
And I’ll give you two good reasons why.

First, let’s compare this tiny insignificant problem to the real issues of the day. As I’ve just pointed out, there are more than a few big problems which threaten the well-being or existence of all of mankind. And what you do with important problems is try to solve them.
That’s not so easy, as it turns out. We don’t know how to solve any of mankind’s big problems. War rages on, people die of cancer, prices keep going up, and this global warming thing just won’t go away. But despite green technologies, peace conferences, advanced farming technologies and cabalistic charms, at the bottom line we cannot right now solve any of these problems.
But let’s be optimistic. The world has billions of humans in it, surely a few of them might be smart, and maybe with enough focus we might come up with a solution to a problem. Now... which problem should we focus on?
Curing cancer won’t put a stop to wars, or to hunger. It also won’t make better software.
Reversing global warming won’t abolish war and human trafficking. It, too, won’t make better software.
But let’s look at the software. Could software end war? Probably not. But it’s very likely to be an indispensable factor in finding a cure for cancer. Solving world hunger will probably rely on several fascinating branches of engineering, all of which rely on software. Global warming is technically a hardware issue, but if you’re going to analyze weather patterns all over the globe and things that affect them, I guarantee that you won’t be doing it with an abacus.
To sum up: while many big and difficult problems trouble mankind, badly written software is the only problem whose solution is likely to facilitate the solutions to other serious problems.

Second, software is more than just words on computers. If you’re a singularitarian (and why wouldn’t you be?) then you probably know that software is going to become for us what DNA was for the first single-celled organisms that formed in the primordial ooze. It is the building block of the next phase of the meta-evolution.
But even if you’re not a fan of Ray Kurzweil, let’s put it this way: when you write software, you use software to write, then more software to compile, then more software to run. Eventually you use software to allow other software to distribute your software to other people. And the layers are piling up with incredible speed; why, just a few decades ago programmers were working with individual bits and processor instructions, and now just a few words in Python or SQL could launch millions of calculations.
And where does that software end up? Why, everywhere! Your cellphone has software, your microwave has software, your air conditioner has software, your airplanes and spaceships and medical devices have software. Go to a store, buy something (using software to buy, and more software to pay), and you can bet that some software was involved in its production. The automatic door on the way out probably has software too. Your car has software, the traffic lights that tell you to stop have software and so does the camera that lets the police know if you don’t, the road you’ll drive on next year will hopefully be designed using software, and people in suits will approve its budget after using software to look at a presentation made by software. And if this road happens to be in Nevada, then apparently the car can be driven completely by software as well.
All of those things sum up to a hell lot of responsibility, and this responsibility accumulates. It accumulates fast. A chain is as strong as its weakest link, after all, and we have increasingly long chains of software relying on software, and you only need one to break.

These two reasons, in a nutshell, show that solving this problem is good, and that not solving this problem is bad.
And it’s not like software is all flawless. Not even the really important bits. It might not be common, but it’s certainly not unheard of to have medical devices that kill patients or a spacecraft that crashes as a result of careless programming.
Now, a lot has been said, written, and probably yelled about software development and how it should be done. There are standards, and methodologies, and systems. But for some reason, they never address the point so succinctly conveyed in the quote at the top of the page.
Source code is not just a product. The source code of any module is a tool for another programmer, and it needs to be readable and predictable and safe. The source code of any big project written today is a medium of communication with whomever might work on this project next year, and once again it needs to be readable and predictable. At the bottom line, most serious code you write will, at some point, have to be read, and this is where the difference between good code and bad code lies.
It’s not about optimization, and it’s not about what the code actually does. Serious mathematicians have shown that all programming languages that are Turing-complete (which is practically all of them) are equivalent. Whether it’s a language like Ada that was developed by the USA Department of Defense for maximum robustness, or one like Intercal which was written as a joke by a couple of students, any calculation that can be done in one language can be done in another. You could do it all in Assembly and have a really fast program and not have to bother about fancy compilers. But you don’t do that, because the difference is in the readability.

As this realistic illustration shows on the left, even good code is likely to make the unsuspecting reader say WTF and hope that whoever wrote it went to see a doctor before it was too late. Any serious code is likely to do complex, non-trivial things, that the reader might not be expecting. Which is all the more reason to try to make the code as easy to understand as possible, to avoid the situation depicted on the right.

As a programmer, it’s your responsibility to write your code in a way that will make it as easy to read and understand as possible. The more readable it is, the less effort people have to make when they come to use it, change it, fix it, or just read it for fun. Coming from the other side, hard-to-read code is very dispiriting and automatically makes the reader pessimistic about their chances of understanding it. And if all that wasn’t enough, then as a free bonus you will find out that readability and abstraction are hopelessly coupled; making the code more readable tends to lead to better abstraction, and vice versa.

I hope that all of this was enough to convince you that readable code is a worthy ideal to strive for. That leaves only the tiny detail of how to make the code more readable, and I intend to start writing about that in great detail.


  1. Strictly speaking, most of the devices you mentioned use firmware, not software - of course,
    both are code, but quite a different one.

    Congrats, though. Looking forward for more.

    1. The difference between firmware and software is merely the medium. Most generic development principles should apply to both of them equally.

      Thanks, there will be more later this week :P