Three is a pattern
Finding a balance between prepping for future or doing repeated work is not easy. Whether it is about sharing advice one-on-one vs. writing it down into a blog or refactoring code into reusable blocks or setting up extra tooling for personal notes’ system, the decision time comes up at some point.
Over the years, I’ve found the rule of “three is a pattern” to be quite useful in balancing this.
Here’s how it works:
First time I do something, I don’t yet know (even if I might have an assumption) if I’ll do it again. Even if I’d have a really strong assumption that I will, I don’t know all the details yet. Extracting it into something reusable at this stage would be premature.
We’d put work into generalising/abstracting away something based on a sample size of 1. Sometimes it works, especially if there’s prior art from previous similar cases.
Second time I do the same thing, I’m starting to notice similarities and differences but even then it’s usually not worth of the extra work.
Third time it happens, I notice a pattern. The similarities get refined and I see that there’s enough of them for now to be a good time to put it into a format where the fourth, fifth and all the following times become easier.
Writing advice in blog
With writing, the rule mostly works as a threshold when it’s time to write it down if I haven’t already. I often write and share things I’ve learned even if nobody asked. But once I hear the same questions pop up over and over again, the third time is when it goes into the blog so I can share it alongside with personal additions specific to that question or case.
For example, one of my popular posts, How to ask help for technical problems? was born from seeing patterns of inefficient help requests over and over again. Search your notes stemmed from multiple recent discussions around the topic and I wanted a way to point towards something instead of always saying the same things over and over.
Refactoring code
Writing code is partly about discovering requirements and restrictions. With every iteration of a software, we learn new things about the world, the usage and users of the software and how business requirements relate to it.
Reusable code in form of functions, classes, modules, libraries or frameworks is a wonderful thing but prematurely abstracting can lead to clunky abstractions and can make the usage of those abstractions harder than just copy-pasting old code and adjusting it a bit for the new use case.
That’s why the the rule of three is a pattern comes handy. First time you don’t know about the future so write it as it solves the problem at hand. For the second time, take what you can from the first and adapt it to the use case at hand but keep both of them on their own paths.
On the third time, you may start to notice the patterns (or lack of them) and that can guide you towards a better abstraction which you can then put into place, replacing the old individual code snippets.
Templates, plugins and other extra tools
Last weekend I created a new Obsidian vault for my Advent of Code 2024 Digital Garden. If you’ve spent any time in the Obsidian webosphere (forums, Reddit, Youtube, social media, etc), you have probably run into a million opinions and questions of which configurations and plugins one needs to be productive.
In my opinion: start with none. Let the emerging needs guide you towards what you might need.
As I was writing my Advent of Code solution explanation for day 3, I noticed I kept peeking into previous days’ notes to see what my structure for those notes were. That made me notice my first useful abstraction: creating a daily template.
On day 1, I didn’t know I needed one, neither on day 2. By day 3, I had gotten to a spot where I realised I want certain consistency in my headings and flow of explanations to make it easier for people to follow day after day.
So I made my first template, combining the common bits from first 3 (which were not identical, mind you). On the fourth day, I can be confident that 1. I’m still writing these notes and 2. I’m following a pattern so I can now shortcut into that with a run of a command.
Benefits of the rule
One of the benefits I already discussed: it helps avoid premature optimisation/abstractions.
The second benefit is that it helps you guide your efforts. You don’t have to worry about “should I or should I not?” in the first or second run. Just do it. If it never comes around again, you avoided extra work. If it does, then the first 3 iterations guide you towards a more sensible next step that will help you save time in the future.
Third time is the starting point, not the end. Everything is iterative so keep improving those abstractions as time goes on and you learn more about them and how they fit into the longer continuum.