I was reading a delightful Joel Spolsky article that was posted to my company Slack today - it was originally published in 2001, and I had read it many years ago. As with most of Joel's articles, I assume I nodded along and filed it away to think about. This time though, I found myself wishing it had included a bit more information.
The article is great, but needs some augmentation. The title of the article is "Good Software Takes Ten Years, Get Used To It" - a summary of the article could be:
- Historically, software takes a long time (years) to get to 1.0
- Historically, software growth/adoption is exponential.
- Historically, software is pretty low quality until it has doubled in size many times, which historically does not happen quickly.
- Despite a lot of press, software doesn't really become good until 10 years from when someone started working on it.
There's some cause/effect muddling here - for instance it's unclear to me if there's a relationship between growth and quality being implied here, but he does have a large section of helpful advice explaining some counter-productive myths and debunking them ("Business Mistakes"), which is certainly welcome.
However, the premise of the article appears to be that at a certain point in time (10 years, apparently), a piece of software is complete, and no longer can be improved. While I wish that were true, I've never seen it in the wild. So I'd like to propose an alternate theory of software completion:
Software Isn't Ever Necessarily Good No Matter How Old It Is, And In Fact Most Software Shouldn't Even Try To Be Good
Some definitions are in order. When I say Good, I mean (and believe Joel to mean) that it is software that is serving a useful, necessary, and economically self-sufficient purpose, and that the users of said software are satisfied in the software's performance and functionality such that a large majority of the users would prefer that it did not change dramatically.
I believe that then the time it takes to write "Good" software is porportional to how complex the software is in a "Good" state.
Joel worked on Excel, and I think 10 years is a very reasonable timeline for how long I'd expect Excel to take. And I actually think that if a team of engineers were given Excel in 2001, it may have kept its feature set -- maybe adding a few parity features to take advantage of fast internet speeds and processors -- but generally people would know what it's good at and customer expectations and value could continue to be satisfied.
You may know that with the benefit of history, that isn't really what happened. I suspect that excel's feature list looks a lot like the chart at the beginning of Joel's article, infinitely exponentially exploding in the 20 years since the article was published. In fact, I've worked directly on an excel competitor, and even as a small part of a larger whole of features, it was always the bear when it came to complexity, and many PMs had the opportunity to make it worse by imagining what might be possible with it.
Perhaps this is an issue with Excel as a product (it is, after all, effectively a programming language and computer all rolled into one). But I suspect that we can extrapolate some useful lessons here.
A counter point may be a simple Linux program, which likely could achieve the reliability of Excel 2001 in a much shorter time period. Given the resource consumption of 0, it also is economically self-sufficient. Adoption wise, it would trend with Linux adoption, so on the same curve. I don't have a study for this, but I think our intuition can tell us that outside of how much more money it made than cost, a program like
tar roughly follows the same pattern as Lotus Notes, in a fraction of the time - as a result of it being a fraction of the complexity.
All this to say - to refine Joel's thesis, the temporal boundary of 10 years probably isn't that useful. In fact, a math equation probably isn't useful at all, given that the languages, features, and implementations, among other things like the backgrounds of the authors, will impact the raw values when answering "how long will it take to be good". However, there are likely some much more addressible targets to help make good software, that will help answer the "how long" question:
Is your software even capable of being good
Much software I've seen built in the last 21 years doesn't even have a chance of clearing the bar I set above. It's just there to make money, and is an arbitrage tool - imagine a high frequency trading robot or the Uber app - these pieces of software are entirely bound by the markets they exist in, and cannot possibly be good for any duration of time, given that the markets they participate in are adversarial and changing. There is no feature in uber that would make drivers want to be paid the amount that uber wants to pay them. The competing forces meant the software is in a perpetual state of being bad software. To write software in this context, you'd be wasting your time if you took the time and care on every feature to refine it to being Good. The harsh reality is that more than likely, you'll just be making it harder for the business to succeed by writing Good code. I strongly suspect that a management style of "plan to throw out the codebase every 2 years" would be far more effective in these environments. In observing these types of companies, that often is the result regardless of the plan.
When is your software good
How will you know if your software is good? Who will decide? What is the last feature you will build? These are hard questions to answer in an exponential growth based economy, but I'd argue that most software these days starts out with ambitions that are not possible on a 10 year time scale. PMs are pretty liberal and young engineers are hungry to ship. As Joel noted, the myth of "Internet Time" has long been propagated - the idea that shipping more often is the same as shipping more/better software is long debunked. Slack ships hundreds of times a day and still barely works. A potential tonic for this problem is to create clear understanding of the goals across the company, which is far harder than it sounds. In fact, if you work in software, what would you consider the "end state" of your software if you could stop time and finish it up? If you can even answer that question, ask your PM or a coworker - did they say the same thing?
In summary - after writing software the entire 21 years this article has existed on the internet, I'd offer this guide on how to write good software:
Determine if your software can even be Good. If so, agree on a simple feature set and improve your software for 2-5 years. At this point, you may have customers. If you do, seek to implement the minimum amount of improvement possible to make them as happy as possible. In an additional 5 or so years, it is possible that your software will be as good as Lotus Notes, one of the best pieces of software written.
However, I don't think most people should even aspire to write software this way. Instead, I'd offer a few alternative paths:
Write less software, or software with less economic requirements. Lotus Notes is extremely complicated, and at its peak was capable of supporting a large number of employees and customers. Find somewhere on the spectrum between Lotus Notes and a simple linux utility that will satisfy your economic requirements and your timeline requirements. Or perhaps just work on something that doesn't need to make as much money. Do you really aspire to work on a team of thousands? You can't, however, build something with high complexity quickly. I suspect this was Joel's original point. Most startups fail because they fundamentally attempt to do more than they possibly can with their runway. Why not do something well instead, and fail because you were wrong that people would like it? At least that way you can write Good software before you fail.
Don't write good software. It's not very profitable compared to imperfect-yet-functional software and if your company is going to scale to hundreds of engineers anyway, your good sofware will drown in features. You'd need 100 years to write Uber with Good software, and in 100 years nobody is going to drive their personal car for 90 hours a week for less than minimum wage, so the software won't be able to make enough money for you to keep it running anyway. This doesn't mean you shouldn't write readable software, or that it's acceptable to not care about the quality of the software you write -- but it does mean that you probably don't need to strive for perfection, and you definitely don't need to write a platform. You can have classes that are thousands of lines long. Optimize for velocity, not quality. Maybe, if you get lucky, people will like your software enough that you can think about spending the next 10 years rewriting your software, this time writing it well.
Your software is temporal, make it fit the team and customers it has now, not an aspirational target in the future. If there's demand for Good software in your space, you'll have 10 years lead time to get started.