Perfect is the Enemy of Done

2024-05-24

#soft-skills 

I haven’t posted in a while. I have a ton of writing topics identified and a few draft posts already written, but I have a really hard time finishing each post and sending it out into the world. I see this behavior in my coding side-projects too. I just want everything to be perfect. This is the subject of this (purposefully) quick and messy post.

As the saying goes

I forget where I originally heard it, but the phrase “perfect is the enemy of done” really resonated with me. Here is wikipedia’s definition:

Perfect is the enemy of good is an aphorism which means insistence on perfection often prevents implementation of good improvements. Achieving absolute perfection may be impossible; one should not let the struggle for perfection stand in the way of appreciating or executing on something that is imperfect but still of value.

wikipedia

I also like the Chinese provenance further down in the article: “Better a diamond with a flaw than a pebble without one.”

Why it’s easy to get distracted by perfection

Many modern programming languages have so many “distractions” built into the language or ecosystem. You can’t write Golang or Rust without fist doing a ton of ceremony to ensure the types are correct. It’s also expected (if not required) to write a ton of JSDocs for your classes, functions, types, etc. Then you need to ensure you’ve named everything correctly and you’re following best practices.

Don’t get me wrong, I think that it’s important to focus on strong and correct types with solid documentation…when it’s ready for production. That said, there’s no point in bikeshedding on the types for a function you might throw out two commits later.

How to stop yourself

Stopping yourself from over-rotating on meaningless (or untimely) topics requires frequent self-check-ins:

“Is this important right now?”

“Can I focus on this later?”

There are also some tactical choices you can make to help along the way. Set time limits for a task. For example, time box 20 minutes to try and solve a complicated type. If you’re unable to solve it, slap a FIXME on it and (if your language supports it) an any type. Chances are, if it’s that hard to define a type for your data, you probably have the wrong data structure (and are likely to refactor it anyway).

If the choice of program language is up for debate, consider starting off in something that has less “distractions”. I’ve found that Python, Lua, and (to a lesser extent) Go, provide the basic tools and then get out of the way. Sure you can add types to your python, but there’s nothing stopping you from opening up a new .py file and knocking out the problem. You can always convert it to something (like Rust) later. I’m currently taking this approach with a battlesnake I’m building.

Final thoughts

As with everything, moderation is important. However, when possible, solve the task first and then refactor it to be better. Never shoot for “perfect”, only “good enough for now”. If you have time and want to strive for better, do so…but only after you’ve shipped something.