Simple, correct, fast: in that order(drewdevault.com)
drewdevault.com
Simple, correct, fast: in that order
https://drewdevault.com/2018/07/09/Simple-correct-fast.html
344 comments
I would argue that correct is more important than simple.
Consider timezones: it's simpler to pretend there's 24 time zones, one for each hour. But the correct assertion is there's 37 time zones (as of this writing). So, the simple solution results in a third of your potential user base having issues.
Other issues to pick: accessibility, cross-browser compatibility, legacy device compatibility... the list goes on.
Consider timezones: it's simpler to pretend there's 24 time zones, one for each hour. But the correct assertion is there's 37 time zones (as of this writing). So, the simple solution results in a third of your potential user base having issues.
Other issues to pick: accessibility, cross-browser compatibility, legacy device compatibility... the list goes on.
Is the software engineering profession doomed to lose its memory every generation? The premise of this post is ridiculous:
>The single most important quality in a piece of software is simplicity.
How panglossian, imagining the best of all possible worlds. Well, the world is intrinsically complex, as Fred Brooks explained in his No Silver Bullet essay from 1986[0].
"The complexity of software is an essential property, not an accidental one."
Sure, there is accidental complexity in most software problems, that can be tackled with skill and experience, and maybe reduced to zero. But then you are left with the essential complexity of the world. And you are done reducing the complexity; you can only manage it from then on. The world is very, very complex and it is a pipe dream to imagine that we can eliminate its complexity just by some bold engineering.
[0] http://worrydream.com/refs/Brooks-NoSilverBullet.pdf
>The single most important quality in a piece of software is simplicity.
How panglossian, imagining the best of all possible worlds. Well, the world is intrinsically complex, as Fred Brooks explained in his No Silver Bullet essay from 1986[0].
"The complexity of software is an essential property, not an accidental one."
Sure, there is accidental complexity in most software problems, that can be tackled with skill and experience, and maybe reduced to zero. But then you are left with the essential complexity of the world. And you are done reducing the complexity; you can only manage it from then on. The world is very, very complex and it is a pipe dream to imagine that we can eliminate its complexity just by some bold engineering.
[0] http://worrydream.com/refs/Brooks-NoSilverBullet.pdf
I can't really understand the equivocating tone a lot of folks are taking in response to this, and more importantly I can't wrap my head around how you could make such a statement in the first place: without correctness you've got nothing. Stating authoritatively that correctness comes after...anything is incomprehensible to me.
It's possible to have a correct solution that is neither simple nor fast, and it can be worth your while to speed up a correct solution while sacrificing simplicity. So there are trade-offs involved in the relationship between simplicity and speed, but correctness is not negotiable. Acknowledging that all software has bugs is not the same thing as throwing out correctness as your first and primary objective in implementing an algorithm, and accepting that your solution may only be partial or fail with certain inputs is fine if that is acceptably correct for the problem at hand, but ascertaining that still comes first. Preferring simplicity over complexity because it makes debugging, profiling, etc. easier is not a reason to insist that correctness can go out the window in service to simplicity--who cares if you've removed all the bloat from your code if it's wrong?
It's possible to have a correct solution that is neither simple nor fast, and it can be worth your while to speed up a correct solution while sacrificing simplicity. So there are trade-offs involved in the relationship between simplicity and speed, but correctness is not negotiable. Acknowledging that all software has bugs is not the same thing as throwing out correctness as your first and primary objective in implementing an algorithm, and accepting that your solution may only be partial or fail with certain inputs is fine if that is acceptably correct for the problem at hand, but ascertaining that still comes first. Preferring simplicity over complexity because it makes debugging, profiling, etc. easier is not a reason to insist that correctness can go out the window in service to simplicity--who cares if you've removed all the bloat from your code if it's wrong?
I think to those that are asserting that correctness comes first are somewhat missing the point. One, a simple solution is still a solution, that is if your code doesn't solve the problem, you can't stop. I think the author is suggesting that truly _correct_ code (code that produces the correct output under all circumstances) is only attainable iteratively, and if your code is not simple (and let's also remember here: that simple ain't easy!) than reaching correctness or performance will, in the main, be quite difficult. Not only will it be increasingly more difficult to reach a state of correctness again after a bug is found, and it will be found, but even measuring performance will become increasingly challenging. At least that's the lesson I take.
Performance in most non-trivial software, and especially infrastructure software, is architectural. In many cases an architecture that will allow your software to be performant requires a commitment to a very substantial amount of software complexity upfront to ensure adding performance is much simpler (or even possible) later. There are also rarer cases where correctness is not simple, so there is no trivial path between the simple implementation and a rigorously correct one. While "simple" is easier for the software engineer, customers pay for "correct" and "fast".
In my own area of work (database engines), the common mistake is that inexperienced designers do focus on simplicity first, instead of correctness and performance, not understanding that it is at best difficult and sometimes impossible to add correctness and especially performance later. The fast win of "simple" can turn into nearly insurmountable technical debt when you are asked to deliver scale and performance. People often grossly underestimate the minimum amount of initial implementation complexity required for good architecture.
There are many types of software where "simple, correct, fast" is sound advice but it is far from universal.
In my own area of work (database engines), the common mistake is that inexperienced designers do focus on simplicity first, instead of correctness and performance, not understanding that it is at best difficult and sometimes impossible to add correctness and especially performance later. The fast win of "simple" can turn into nearly insurmountable technical debt when you are asked to deliver scale and performance. People often grossly underestimate the minimum amount of initial implementation complexity required for good architecture.
There are many types of software where "simple, correct, fast" is sound advice but it is far from universal.
I think this is lacking a definition of simple. And where in the problem space do we desire simplicity? Simple in the implementation (and conversely complex in the interface? ie: C-style libraries?) Or complex in the implementation but simple in the interface? (ie: Haskell/FP style libraries?)
My definition of simple software is software that I can validate the correctness of using only equational reasoning and the mathematical tools used to carry it out without any specialized knowledge or verification systems.
If I have to learn a new way to reason about a software system in order to understand it then it is complex.
A priori any system written in C fails this litmus test: one must understand and identify the many ways that undefined behavior can enter into their program and be leveraged by their compiler. One cannot reason about a local expression in the presence of global effects and unchecked side-effects. And if it is possible to write a correct C program it takes considerable effort and the use of very specialized verification tools.
There are many reasons to prefer C however; if we're willing to live within some tolerance of "correct" and "incorrect" then we can leverage a tool-chain that can produce highly performant code... but then we're forced to restrain ourselves from introducing complexity instead of spending that effort on other things.
My definition of simple software is software that I can validate the correctness of using only equational reasoning and the mathematical tools used to carry it out without any specialized knowledge or verification systems.
If I have to learn a new way to reason about a software system in order to understand it then it is complex.
A priori any system written in C fails this litmus test: one must understand and identify the many ways that undefined behavior can enter into their program and be leveraged by their compiler. One cannot reason about a local expression in the presence of global effects and unchecked side-effects. And if it is possible to write a correct C program it takes considerable effort and the use of very specialized verification tools.
There are many reasons to prefer C however; if we're willing to live within some tolerance of "correct" and "incorrect" then we can leverage a tool-chain that can produce highly performant code... but then we're forced to restrain ourselves from introducing complexity instead of spending that effort on other things.
Not convinced. Simplifying a correct implementation can be easier than correcting a simple implementation. Eventually you need to find the correct model and then everything else will follow easily, but a complex implementation that does the right thing will tell you a lot more about what the correct model is than a simple implementation that doesn't do the right thing.
Without defining what "simplicity" and "correctness" are supposed to mean, this article is empty of content. The title appears to be riffing off of the famous saying "First make it work, then make it right, then make it fast" ( http://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast ) which is supposed to be a warning against premature optimization (one that is less often taken out of context than Knuth's famous saying). But by lumping both "making it work" and "making it right" under "correctness", it makes it appear that the author values simple software that doesn't do its job over complex software that does. And the problem is that you can't easily slot simplicity in by drawing a stark dividing line between "making it work" and "making it right", because it's a continuum of correctness. At best, simplicity is more important than performance, much of the time. But at the end of the day the point of software is to perform a specified task, whether or not it is achieved in an aestheically pleasing way underneath.
This is great, but completely lost on the crowd if what Simple means isn't understood.
One of the best clarifications of what it means to be Simple, to put it out there, is [1]; but the key point: Simple != Easy.
Simple means minimal coupling, high-cohesion etc etc.
Yet IME many developers do not understand the distinction and mistakenly believe that easy is the same as simple, and are willing to couple the hell out of the world under some false notion of "simplicity"...
[1] https://www.infoq.com/presentations/Simple-Made-Easy
One of the best clarifications of what it means to be Simple, to put it out there, is [1]; but the key point: Simple != Easy.
Simple means minimal coupling, high-cohesion etc etc.
Yet IME many developers do not understand the distinction and mistakenly believe that easy is the same as simple, and are willing to couple the hell out of the world under some false notion of "simplicity"...
[1] https://www.infoq.com/presentations/Simple-Made-Easy
This title is misleading. The post actually says that the reason "simple" comes first is because without it you can't have "correct" (nor "fast", not that that matters so much). So he's not saying simple is most _important_, just that it comes first chronologically, and has the other two as consequences.
Think about it in terms of each choice you make.
I have a simple solution and a complex solution. Does the simple solution meet the requirement(s) before me? If so, I prefer it. Let's move on to the next requirement and consider my options again.
The alternative might be to look at your requirements, but choose a complex solution (over a simple one) because you think it might meet other requirements, either ones that have not yet been identified or ones you think are likely to happen in the future.
Are there times that the more complex solution wins? Probably. Consider you want to write a blog. You know that you can create an HTML (text) file and slap it on a web server and your blog has started. But if you've done this before, you might also know that you can throw WordPress on your server for a little more up front pain. You know you want comments and word clouds and date/time stamps and navigation. So you choose the complex solution. (You also know that you know face potential security implications, upgrades, dealing with users causing trouble with comments, having the PHP/MySQL infrastructure/hosting requirements...) Maybe you just wanted to dump your thoughts to the internet. Maybe the text file approach was better...
It may just be another way to say "avoid gold-plating your software."
I have a simple solution and a complex solution. Does the simple solution meet the requirement(s) before me? If so, I prefer it. Let's move on to the next requirement and consider my options again.
The alternative might be to look at your requirements, but choose a complex solution (over a simple one) because you think it might meet other requirements, either ones that have not yet been identified or ones you think are likely to happen in the future.
Are there times that the more complex solution wins? Probably. Consider you want to write a blog. You know that you can create an HTML (text) file and slap it on a web server and your blog has started. But if you've done this before, you might also know that you can throw WordPress on your server for a little more up front pain. You know you want comments and word clouds and date/time stamps and navigation. So you choose the complex solution. (You also know that you know face potential security implications, upgrades, dealing with users causing trouble with comments, having the PHP/MySQL infrastructure/hosting requirements...) Maybe you just wanted to dump your thoughts to the internet. Maybe the text file approach was better...
It may just be another way to say "avoid gold-plating your software."
The OP's advice, if applied in CPU industry, would be disastrous. Modern desktop/server CPUs are incredible complex... in order to drive maximum performance. Pipelining, OOO execution, branch prediction and speculative execution: these are all features that introduce tremendous amount of architectural and design complexity. In many cases, they also harm correctness, because they can lead to functional and security bugs.
And yet, if you try to compete with Intel with a CPU missing the above optimizations, you will get absolutely creamed in the marketplace. No one, not even those touting the importance of simplicity and correctness, will buy what you're selling.
Today's free market is too complex for these overly simple rules. Choosing between simplicity, correctness and performance, is a complex tradeoff that needs to be made on a case-by-case basis. Trying to find shortcuts to avoid these analyses may feel liberating... but you're ultimately only shooting yourself in the foot.
And yet, if you try to compete with Intel with a CPU missing the above optimizations, you will get absolutely creamed in the marketplace. No one, not even those touting the importance of simplicity and correctness, will buy what you're selling.
Today's free market is too complex for these overly simple rules. Choosing between simplicity, correctness and performance, is a complex tradeoff that needs to be made on a case-by-case basis. Trying to find shortcuts to avoid these analyses may feel liberating... but you're ultimately only shooting yourself in the foot.
I often repurpose a famous quote from Mark Twain (about letter writing) for the topic of simplicity:
> I didn't have time to write a simple program, so I wrote a complicated program instead.
This is in my experience more than just a clever turn of phrase: the vast majority of software projects (or features etc.) move from _simplistic_ to complicated, and rarely from there toward simplicity. The end result is exactly what this author describes -- a complex mess that's difficult to reason about and rarely performant.
Few of us (usually myself included) are willing to devote the time and effort required to achieve true simplicity.
> I didn't have time to write a simple program, so I wrote a complicated program instead.
This is in my experience more than just a clever turn of phrase: the vast majority of software projects (or features etc.) move from _simplistic_ to complicated, and rarely from there toward simplicity. The end result is exactly what this author describes -- a complex mess that's difficult to reason about and rarely performant.
Few of us (usually myself included) are willing to devote the time and effort required to achieve true simplicity.
I prefer: “the strategy is definitely: first make it work, then make it right, and, finally, make it fast”.
http://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast
http://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast
Apparently everybody knows "correctness" comes first. But that is the whole point of this article: It argues that complexity will reduce correctness, and thus simple should come first.
Please NOTE that I am not saying that I agree or disagree with this article.
Please NOTE that I am not saying that I agree or disagree with this article.
My take on this from like 10 years ago:
http://www.expatsoftware.com/articles/2007/06/getting-your-p...
I came up with Readable as the top priority, followed by Debuggable and Maintainable. I suppose one could combine that into "Simple" if one liked.
But yeah, Fast was already at the bottom of the list. Even back then.
http://www.expatsoftware.com/articles/2007/06/getting-your-p...
I came up with Readable as the top priority, followed by Debuggable and Maintainable. I suppose one could combine that into "Simple" if one liked.
But yeah, Fast was already at the bottom of the list. Even back then.
The simplest code is an empty file. And yet, we live in a world with complex software. There are tradeoffs, but this article doesn't help you make them.
I think this article may be guilty of overstatement. It's an ever more common sin, as overstatement seems have become a preferred method for communicating thoughts and ideas (and products, though that's nothing new).
Is there a need to overstate to cut through the noise and get your point across or your message heard? Maybe, but it seems unfortunate that when people have some truth or wisdom to share, there is a felt need to amplify and polarize it.
This article has good things to say about the importance of simplicity in code and implementation. I'm fine with value judgements as long as they convincingly define the values they are judging and show evidence that the facts have been thoroughly weighed. 'Correctness' is an ill-defined villain here and the article would do better to state the benefits of simplicity and experiences the author has had with systems designed without simplicity as a first-order goal.
Then again, perhaps I ask too much. Also, I've never had an article on the front page of Hacker News, so what do I know.
Is there a need to overstate to cut through the noise and get your point across or your message heard? Maybe, but it seems unfortunate that when people have some truth or wisdom to share, there is a felt need to amplify and polarize it.
This article has good things to say about the importance of simplicity in code and implementation. I'm fine with value judgements as long as they convincingly define the values they are judging and show evidence that the facts have been thoroughly weighed. 'Correctness' is an ill-defined villain here and the article would do better to state the benefits of simplicity and experiences the author has had with systems designed without simplicity as a first-order goal.
Then again, perhaps I ask too much. Also, I've never had an article on the front page of Hacker News, so what do I know.
One of the lessons I've learned (that this article echos upon) is that you should _always_ factor the "long term cost" of adding a feature.
When I first started building TrueJob (job board software), I'd add in all these really cool features that made my app -- and at the time, they felt really useful. But over time, people weren't using them, so I built more features.
But then the old features I had built broke, so I had to fix them. And then they lagged behind the quality of other features I had written them, so I had to update them. And after doing this 5-10 times (as the software evolved and I dramatically increased the complexity of my application), these features that no one used really were painful to keep coming back to, but now enough loud users were using them that I couldn't remove them.
It made me really value the projects where we polished and did just a very few things, but did those very very well -- it lead to higher customer satisfaction, and less pain in the long run for us.
When I first started building TrueJob (job board software), I'd add in all these really cool features that made my app -- and at the time, they felt really useful. But over time, people weren't using them, so I built more features.
But then the old features I had built broke, so I had to fix them. And then they lagged behind the quality of other features I had written them, so I had to update them. And after doing this 5-10 times (as the software evolved and I dramatically increased the complexity of my application), these features that no one used really were painful to keep coming back to, but now enough loud users were using them that I couldn't remove them.
It made me really value the projects where we polished and did just a very few things, but did those very very well -- it lead to higher customer satisfaction, and less pain in the long run for us.
I fully buy the argument that code is a liability, while the underlying algorithm, or the overlying service is the asset. Following this line of thinking encourages the writing of simple code.
Far more of a problem than code complexity is the lack of systems thinking when applied to programs. Various factors (abstraction, delegation, nicer APIs, solid products, SaaS, "microservice" trends, package managers and bundlers) have encouraged offloading much of the computation and data flow to other products, whose strengths and liabilities become your own if you make use of them. One-liner lambdas might be simple code, but they're often coupled to a maze of other cloud services, and the complexity there is coming from the dependency substrate, whose shape can't even be expressed in an imperative or declarative notation like code.
In truth, code and libraries and services feed into systems, and those systems must be understandable if correctness and maintainability are a goal.
Far more of a problem than code complexity is the lack of systems thinking when applied to programs. Various factors (abstraction, delegation, nicer APIs, solid products, SaaS, "microservice" trends, package managers and bundlers) have encouraged offloading much of the computation and data flow to other products, whose strengths and liabilities become your own if you make use of them. One-liner lambdas might be simple code, but they're often coupled to a maze of other cloud services, and the complexity there is coming from the dependency substrate, whose shape can't even be expressed in an imperative or declarative notation like code.
In truth, code and libraries and services feed into systems, and those systems must be understandable if correctness and maintainability are a goal.
Some other formulations:
- Occam's razor https://en.wikipedia.org/wiki/Occam%27s_razor
- "Simplicity is the ultimate sophistication" (Leonardo da Vinci)
- "Less is more" (Mies Van Der Rohe)
- "Make everything as simple as possible, but not simpler" (Albert Einstein)
- Occam's razor https://en.wikipedia.org/wiki/Occam%27s_razor
- "Simplicity is the ultimate sophistication" (Leonardo da Vinci)
- "Less is more" (Mies Van Der Rohe)
- "Make everything as simple as possible, but not simpler" (Albert Einstein)
My reaction to both the title is similar to that of other commentors: correctness should go first!
However, the general idea appealed to me, so taking a step back, I tried to post-rationalize a similar thought to the author that I could reconcile with my initial reaction. The thought I then had, is that if a simpler solution can be found that solves a significant subset of the problem being solved, then perhaps it is worth adjusting requirements to go for the simpler solution for the fact that it lets us ship faster and with less risk.
Often times we come up with requirements that aren't really "required": showing business stakeholders that dropping a few requirements could enable you to ship six months faster and with far less risk can be a valuable insight in of itself. In essence we are still putting correctness first, but we are changing our definition of "correct" slightly in order to increase simplicity.
However, the general idea appealed to me, so taking a step back, I tried to post-rationalize a similar thought to the author that I could reconcile with my initial reaction. The thought I then had, is that if a simpler solution can be found that solves a significant subset of the problem being solved, then perhaps it is worth adjusting requirements to go for the simpler solution for the fact that it lets us ship faster and with less risk.
Often times we come up with requirements that aren't really "required": showing business stakeholders that dropping a few requirements could enable you to ship six months faster and with far less risk can be a valuable insight in of itself. In essence we are still putting correctness first, but we are changing our definition of "correct" slightly in order to increase simplicity.
"Correct" should, by definition, imply simple and fast. "Simple" tends to be the correct and fastest way to code. Code that runs fast might not be the "simple", but simple code will be the debugged/updated/ported the fastest. I think the author is saying this, but with a more controversial headline (and, intentional or not, controversy creates clicks). After all, this is the premise:
The reason is straightforward: if your solution is not simple, it will not be correct or fast.
This could be reworded in the following ways and the points made in the article would still follow:
If your solution is not correct, it won't be simple or fast. If your solution is not fast, it won't be simple or correct.
The reason is straightforward: if your solution is not simple, it will not be correct or fast.
This could be reworded in the following ways and the points made in the article would still follow:
If your solution is not correct, it won't be simple or fast. If your solution is not fast, it won't be simple or correct.
I interpreted this as advocating for using a model with the lowest-level abstraction that you think will work. If you start with the simplest abstraction possible, you produce a simpler and more maintainable system. You're also in a better position to incorporate further abstraction later as your understanding of the problem space evolves.
This seems like a good opportunity to recommend Rich Hickey's talk "Simple Made Easy": https://www.infoq.com/presentations/Simple-Made-Easy
This seems like a good opportunity to recommend Rich Hickey's talk "Simple Made Easy": https://www.infoq.com/presentations/Simple-Made-Easy
What's the right way to cut a bagel?
The obvious solution: Grab a knife, put the bagel on end, and get to slicing.
The commercial solution: Flat and flip. https://www.epicurious.com/expert-advice/best-way-to-cut-a-b...
The mathematician's solution: A Möbius bagel. https://www.youtube.com/watch?v=Ktfo8D3cCr0
The engineer's solution: The bagel jig. http://www.freepatentsonline.com/5228668.pdf http://www.freepatentsonline.com/3347296.pdf http://www.freepatentsonline.com/4807505.pdf http://www.freepatentsonline.com/4747331.pdf
The consumer solution: The bagel guillotine. https://www.surlatable.com/product/PRO-1036557/Sur+La+Table+...
Which is the correct solution? Depends on who you are.
The obvious solution: Grab a knife, put the bagel on end, and get to slicing.
The commercial solution: Flat and flip. https://www.epicurious.com/expert-advice/best-way-to-cut-a-b...
The mathematician's solution: A Möbius bagel. https://www.youtube.com/watch?v=Ktfo8D3cCr0
The engineer's solution: The bagel jig. http://www.freepatentsonline.com/5228668.pdf http://www.freepatentsonline.com/3347296.pdf http://www.freepatentsonline.com/4807505.pdf http://www.freepatentsonline.com/4747331.pdf
The consumer solution: The bagel guillotine. https://www.surlatable.com/product/PRO-1036557/Sur+La+Table+...
Which is the correct solution? Depends on who you are.
I think clear is the most important. Most software projects I've worked on in the past decade have gotten a lot of assumptions wrong. The projects that were able to turn around quickly were the ones that could find busted logic and fix it.
I've been using rspec-inspired testing frameworks to help with this clarity. Whenever I implement some early business logic, I assert that the logic I wrote does what I expect in words using rspec style tests (I've been writing a lot of JS lately so I've been using Jest). The kind that read like sentences: "the tax component applies 2% tax to all purchases above $400." Even if the logic is initially incorrect, being clear in our incorrectness lets engineers and (more importantly) product people quickly identify incorrect assumptions.
The logic to apply that tax in this example may not be simple. Often times, business logic can't be simplified any further and needs to be a bit thorny. In those cases, clarity of purpose is much more beneficial than simplicity, and I've found writing rspec style tests, and forcing myself to translate what the logic is doing into words, helps immensely with clarity. It clarifies my thoughts before shipping code, and it clarifies our business assumptions as a whole when that code is running in production.
I've been using rspec-inspired testing frameworks to help with this clarity. Whenever I implement some early business logic, I assert that the logic I wrote does what I expect in words using rspec style tests (I've been writing a lot of JS lately so I've been using Jest). The kind that read like sentences: "the tax component applies 2% tax to all purchases above $400." Even if the logic is initially incorrect, being clear in our incorrectness lets engineers and (more importantly) product people quickly identify incorrect assumptions.
The logic to apply that tax in this example may not be simple. Often times, business logic can't be simplified any further and needs to be a bit thorny. In those cases, clarity of purpose is much more beneficial than simplicity, and I've found writing rspec style tests, and forcing myself to translate what the logic is doing into words, helps immensely with clarity. It clarifies my thoughts before shipping code, and it clarifies our business assumptions as a whole when that code is running in production.
Anyone can write complex, brittle code, and often even get it to work.
The real superstars solve the same problems with simple code.
I recall a fellow student in CS in the 1980s who used to brag about how many lines of code he wrote to solve an assignment. I never understood that mentality. His programs were always 2-3 times longer than mine. But now that I've had many years in the industry, it almost seems that a lot of people believe more code is better.
The real superstars solve the same problems with simple code.
I recall a fellow student in CS in the 1980s who used to brag about how many lines of code he wrote to solve an assignment. I never understood that mentality. His programs were always 2-3 times longer than mine. But now that I've had many years in the industry, it almost seems that a lot of people believe more code is better.
My approach towards software development has been pretty similar except that my order of priorities is a little different. I prefer:
Correct, simple, fast, in that order.
In other words:
- First get a correct solution working that solves the problem correctly for typical as well as corner cases, hopefully with good test coverage for both typical and corner cases.
- Then improve the solution to make it simpler while preserving correctness.
- Spend time on making it fast when there is actual evidence of performance problems such as data from performance testing with current workload and expected future workloads.
The reason why I like to ensure correctness before simplicity is that many times what might seem like a simple solution initially might turn out to be the wrong idea when all corner cases need to be accounted for. Ensuring correctness first requires me to think through the corner cases well and write test cases early during the development phase. With correctness taken care of and protected reasonably well with test cases, it becomes easier to iterate on the solution and increase its simplicity.
Correct, simple, fast, in that order.
In other words:
- First get a correct solution working that solves the problem correctly for typical as well as corner cases, hopefully with good test coverage for both typical and corner cases.
- Then improve the solution to make it simpler while preserving correctness.
- Spend time on making it fast when there is actual evidence of performance problems such as data from performance testing with current workload and expected future workloads.
The reason why I like to ensure correctness before simplicity is that many times what might seem like a simple solution initially might turn out to be the wrong idea when all corner cases need to be accounted for. Ensuring correctness first requires me to think through the corner cases well and write test cases early during the development phase. With correctness taken care of and protected reasonably well with test cases, it becomes easier to iterate on the solution and increase its simplicity.
Software is rarely correct, because if it is not correct today it will only be correct tomorrow due to skilled interventions, and if it is correct today then it will almost certainty not he correct tomorrow without skilled intervention. The chance of skilled intervention is always low.
Simple software reduces the skill required to intervene.
Simple software reduces the skill required to intervene.
A computer was to control a new assembly line for a car company. They couldn't get the software to work. They called in an outside insultant. The outsider developed a program that worked. (It was more complex.) The book was about the psychology part: The original programmer says: "How fast does YOUR program process a punched card?". Answer: "About one card per second." "Ah!" said the original programmner, "but MY program processes ten cards per second!"
The outsider said, "Yes, but MY program ACTUALLY WORKS". If the program doesn't have to work, I could make it read 100 cards per second.
Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness.