Go small to go big

November 29, 2023

When I’m in the zone coding, especially if it’s a moderately complex program that I understand well, I get hyperfocused. It’s really hard for me to put the project down. The idea for the next building block, the next simplifying refactor, the next feature burn in my brain, and I need to get it out and into code. It is challenging when I have other important tasks to do, people to take care of, or if I have to eat or sleep.

The danger with obsession is of course to rathole—to push yourself beyond your optimal cognitive load, to hyper-optimize, to push a feature too far, too early. I spent a whole day this past weekend implementing a major refactor that ended up being entirely wrong-headed, and I had to git reset --hard and admit defeat. My current implementation is much like the original, just slightly more finessed.

One way I address this (which I forgot to do this past weekend) is to take a grand idea and apply it to something as small as possible. Want to rearchitect a whole class cluster? Try modifying one method in one class. Want to refactor 10 files? Do it with one. Want to rewrite a function that is too large from scratch? Extricate one if branch instead. Want to add a utility library? Start with one function in an empty file.

For me, it turns out that what drives my burning obsession is a constant desire for a taste of progress. Turns out that small progress is far easier to achieve than large progress, so breaking down a grand vision into its smallest possible manifestation allows me to make some progress quickly and satisfy my thirst, and also cheaply test whether the improvement was worth it in the end—and if not, the amount of work discarded would also be small.

Making the smallest possible change that implements your grand vision has a wonderful side effect of making each of your commits do only one small thing. The smallest implementation of your refactor could literally be “Rename foo to bar”, which would make a fine commit message: clear and descriptive. “Reparent Foo class cluster and protocols” on the other hand, will probably be a huge mess of a diff. It’s better to have a commit log of 20 tiny isolated changes than one big one.

So I’m committed to focusing on small progress from now on. When it’s time to step away for meals, to socialize, or to take a walk, I would be satisfied to see that I’ve pushed five small changes to the repo, representing five steps toward a grand plan—a plan that I can now revise with the hindsight of testing if those first five steps were going in the right direction. Because paradoxically, small steps let you make big changes faster.