Are we forever cursed with buggy software?


, , ,

Despite continuous advancements in programming it never feels like software is actually getting any better. It can certainly do more things, but it remains buggy and often unreliable. Is the source of the problem technical in nature, or does it lay more with management?

Quality takes time

All things in programming take time, yet there’s only so much of that to go around. While good practices like testing, review and refactoring definitely save us future time, they also cost us time right now. As uncomfortable as it is to admit, developing “Feature A” and “Feature B” is less time consuming then developing “Maintainable Feature A” and “Maintainable Feature B”.

A company can freely allocate its time. If it really wanted to develop high quality features it could. Instead of rushing out several buggy features, it could instead ship fewer, but more robust, features. Their users would be happier, spreading the word around and showering the company with money. The company would thrive and continue building more high quality features. Yay!

This isn’t happening though, so we must be mistaken about something.

This argument is predicated on a company having competent programmers. I don’t mean great, or even good programmers, but just decent ones that understand at least a bit about quality development. There are bad programmers out there, a lot of them; a company that has primarily bad programmers is doomed regardless of what they prioritize.

The need to survive dominates

A sensible company can not actually freely allocate its time. Consider a small startup; the resources are extremely limited. Whether funded by the founders, bank loans, or external investors, the money is in short supply. Concrete choices have to be made about where to spend that money. It also means there are some hard deadlines when the money runs out.

Consider the target market for this company. Somehow, either by divination, or actual market research, they’ve determined their users want feature A, B and C. Those features comprise their minimal viable product. This may be enough to actually start selling the product, or merely enough to convince investors of a second round of financing.

Determining the minimal viable product is not an easy thing to do. The better it can be done the easier it is to plan with limited resources. Realistically there will be buffer features, things that might be needed, that also consume time. A few months later these features might change. This all leads to increased time pressure.

The desire to produce quality source code is entirely secondary to this minimal goal. It’s of no value to have perfect feature A and B if C is missing. Failing to obtain the minimal viable product means that when the money runs out everybody goes home.

It suddenly seems reasonable to shave off development time now in exchange for future headaches and delays. A sensible project manager will gladly free up a week of time now even if it means a month more later, so long as later is well past the deadline.

Quality is not a boolean value

Cutting back on quality shouldn’t mean a wholesale slaughter of good programming practice. There’s a range of possibilities between having a single massive source file and a well structured repository complete with automated use-case tests. It’s also not an excuse for bad programming. Taking shortcuts is only valuable if it frees up time before the cutoff date; if the consequences start appearing before the deadline then we’re making the situation worse, not better.

Minimal viable products are not concrete things. One hard-to-test feature might be traded for another easier-to-test one. Some features may only need to support a limited set of use-cases. Our unit tests need only to cover those limited cases. In the mobile world we might just support a top-of-the-line device at first avoiding a lot optimization work needed to support older devices. Our initial deployment might also have zero fault tolerance. We endure some minor regressions so long as the main features keep working.

Deciding what can be cut, and what can be done roughly, is not easy. A big part of a programmer’s job is to find the options and communicate the tradeoffs effectively. A programmer must be wiling to compromise on their ideals and find workable, realistic solutions. Overzealous time shaving however, is very likely to be another significant source of low quality software. We’re not trying to save as much time as possible, just enough time to reach the deadline.

Infinite resources and crap pileup

What about a larger company that has a lot of resources? Surely the time pressure would be less and the focus can be on higher quality. Despite having deeper pockets, large companies tend to be project driven nonetheless, and those projects still have limited budgets. The kill deadline might be a softer target, but it’s still there. No project will be fed money forever unless it’s showing results.

There’s evidence that soft targets and abundant resources can lead to a lack of focus, and often a lack of proper motivation. This certainly plays a role in the low quality of some projects. There are actually many problems that can plague development in big companies; to suggest these few problems here are all of them would be naive.

We can also take a somewhat cynical, but realistic view here. Where did the big company evolve from? Yes, a bunch of smaller companies, with a bunch of software that all traded short-term gains for long-term headaches. This gets combined with a bunch of libraries from more startups and lone developers. All those short-cuts come crashing together in massive bugfest pileup!

It’s a business problem

There are obviously many factors at play in software quality, but I believe business pressures are the dominant factor, especially for small companies.

Programmers generally understand the problems in their software. We have big bug lists and many TODO: comments spread throughout the code. We have piles of sticky notes forever removed from the board, and we tune our minds away from the nagging problems. If given the time we could fix more of the problems. Fixing all of the problems however might require an infinite amount of time, but that’s a whole other discussion about diminishing returns.

The market’s tolerance of buggy software also plays a role here. The average user definitely appreciates high quality software, but they demand functional software. It’s just unfortunate that quality demands are at what I consider to be a very low threshold.

I don’t know the solution to this problem, but it certainly isn’t an excuse for sloppy coding. If anything the situation demands we find better ways to program.