Doing One Thing At A Time
When I started programming, I first learned different Algorithms, Time Complexity, Big O Notations, etc. Naturally, I was used to analyze the performance issues when I got a solution.
After all these years of coding, I learned that programming is about doing one thing at a time. Therefore, performance should be a concern for later (if not last). But I still see a lot of people trying to optimize their code upfront, or doing multiple things at a time.
So this post is about the idea of doing one thing at a time, and why it is necessary.
Make It Work, Make It Right, Make It Fast
The best example of doing one thing at a time is the famous quote from Kent Beck:
- Make It Work
- Build the system that can work as specified by the requirements. The code can be messy. The performance can be poor.
- Make It Right
- Refactor the code to make the design right. "Refactor" means that we are not changing any existing behaviors, so the system is still working. Still, performance is not the concern here yet.
- Make It Fast
- Finally, since the system is working and designed well, we can improve the performance of it more easily.
And I favor a rephrased version of this quote:
Make it work, then make it beautiful, then if you really, really have to, make it fast. - Joe Armstrong
#myelixirstatus pic.twitter.com/5X8Z3Wr9zQ
— todd resudek (@sprsmpl) June 18, 2019
Most of the time, we don't need our program to be fast. The extreme cases are often rare.
Often, we don't need our program to be designed well, neither. We only need it to work correctly. We can always refactor it later.
Even so, making the program work by itself is hard enough. We need to make the requirements clear to define what it means by "working". We need to write the program according to these requirements, deploy it, test it. None of them is easy.
Michael Feathers summarized this in a short sentence: “Programming is the art of doing one thing at a time.”
Design One Thing At A Time
Doing one thing at a time doesn't only apply to programming. You can see this philosophy in other activities as well.
Take design activities for example, designers can also take several steps: make it functional, then make it reliable, and finally make it delightful.
Besides this idea in the post, Matthew Ström also gave an explanation on why people often consider Delight first. Due to this cognitive bias called Attribute Substitution, people tend to replace a hard question with a more easily calculated heuristic attribute of the original question.
- When designing, thinking about which font or color to use is simple. The business-related questions are much harder to reason about. So designers can fall into this trap.
- When programming, performance calculation is universal and familiar to programmers. The requirements and architectures are different from project to project, and require a much deeper thinking. So programmers can fall into this trap too.
To fight this cognitive bias, we need to constantly remind ourselves: always do one thing at a time.
This is How We Get Things Done
Jazzwant once said: “Programming is breaking of one big impossible task into several very small possible tasks.” It's basically the same idea of doing one thing at a time. And as we can see above, it's the same for designing process as well. So, can we apply this idea to everything we do? I think the answer is YES!
No matter what kind of products we are building, we can always break the building process into smaller tasks.1 After that, we focus on doing each task well and improving them separately. This is how we get any thing done.
Footnotes:
It sounds like Waterfall but it's actually required by any Agile approach as well. This is a topic for another day.