Finishing Isn’t the Finish Line: On Creativity and Cleaner Code
A few months ago, I came across a YouTube video about creativity that captured something I've long felt. This link should take you to timestamp 11:12. The lines that inspired this blog post are: "creativity is doing more than the first thing you think of," and "humans tend to fixate on an early solution and be satisfied."
If you are a software developer, you may recognize the following scenario: you've been working on a particularly difficult piece of code for longer than you like. It was a bit of a struggle but you finally have a solution that works, even in all the edge cases you could come up with. You're happy you're done with it, and eager to start working on the next ticket.
I'm not the first to argue that this is actually the best moment to take a step back and evaluate whether your work can be improved.
After all, you just "finished" the project, so
- most of the details are still fresh in your mind
- you now know more about the problem domain than when you started
- you can (re-)consider your options without the pressure of having to meet a deadline (this is, of course, assuming you met the deadline when you were "done," with some time to spare)
Look at your code. Are you handling exceptions to a rule? True domain exceptions are much less common than most codebases suggest -- in my experience, they often point to incomplete understanding, not real complexity. With better insight, you can usually replace "an algorithm with an exception to a rule" with one that needs no special-case logic.
A few years ago I was working on a web application (JavaScript/TypeScript) that showed a data set in a graph. The user could select one of a set of functions to apply to the data before rendering. They could also choose not to do this. I remembered learning about, and initially being baffled by, the identity function in university and this was the first time in almost three decades I could actually use it. My QA engineer (a junior, self-taught dev who happens to be a domain expert) was equally perplexed by the concept. "Why don't you program it as an exception to the rule?"
You may say "What's the big deal? As long as the code works..." If you're the only one who has to read your code, it really may not be that big a deal -- although it's probably a good thing not even sound waves can travel back in time, or future-you might give current-day-you an earful.
When someone tells you
I'm traveling from Amsterdam via Barcelona to Casablanca.
you'll likely ask them what they are going to do in Casablanca. When they say
I'm traveling from Amsterdam via Berlin to Casablanca.
then it's natural to wonder what they going to do in Berlin. (Maybe attend a nice house party, ja?) It's inefficient to travel with a detour so when it happens, people are going to look for a reason why it is done.
The same goes for unnecessary complexity in code. By not having your code take detours, you remove wiggle room for confusion in other devs. Not introducing unnecessary complexity to begin with is one of the most fundamental ways to harness complexity.
When a piece of code has an exception bolted on, the question arises: "Is that exception a necessity, or unnecessary complexity caused by the author not knowing any better?"
Developers, in our usual confidence, are often quick to assume the latter and try to refactor the code, possibly overlooking a subtle edge case that was covered by "the exception to the rule" but that now goes unchecked. You don't have to be working on medical software or software that controls a nuclear power plant to potentially have introduced a pretty disastrous problem. Once you've been bitten by that bug, next time you'll make sure you know exactly what the exceptional code is for (and mumble some swear words if, after lengthy analysis, it turns out not to serve a proper purpose).
Takeaway: When a normally simplicity-minded developer writes complex code you don’t fully understand, alarms should go off and you should be wary of refactoring. When a developer who often adds unnecessary complexity does the same, you may be too quick to refactor (Chesterton's Fence).
The mindsets differ: in the first case you assume baseline correctness; in the second you’re suspicious and hesitant.
Which mindset would you rather have your colleagues in when they read your code?
Remember: Git and automated testing are your friends! If you have some time to spare, experiment with simpler solutions. If you circle back after "finishing" and manage to make a meaningful improvement (even a small one) the sense of gratification is hard to overstate. Those last-minute flashes of insight underscore the real heart of creativity: it thrives when you move past your first solution.
Sometimes, the most rewarding breakthroughs happen right after you thought the job was finished.