Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)

Pragmatism and imperfectionism

How to thrive in a world and workplace that are full of imperfections

Pragmatism

  • Work in a way this is practical and sensible given the circumstances, even if it's different from the theoretical "ideal way"
  • Focus on what actually gets the job done for your particular project and case, in a way that's good enough in your context
  • One size doesn't fit all
  • See also It depends
  • See also Keep it simple

Don't expect perfection

Programming is hard and people are not perfect, so don't expect perfection.

  • Don't expect perfection from yourself
    • Just like any other human, you are not perfect
    • You will write code that is not bug-free
    • You will write code that takes shortcuts, doesn't follow some of the project's conventions or is not clear about its intended purpose
    • You will solve problems in suboptimal ways
    • You will fail to see things that are obvious in hindsight
    • You will lack knowledge on some topics that others know a lot more about and that maybe even seem like essential knowledge
    • You will communicate in confusing ways or fail to communicate important information
    • You will misunderstand your colleagues, even if what they say is sensible and clear
  • Don't expect perfection from your colleagues
    • Just like any other human, your colleagues are not perfect
    • Everything that's listed above? Your colleagues will do that too.
  • Don't expect perfection from your codebase
    • Your codebase was likely written under time pressure and based on changing requirements, with everyone working on it an imperfect human
    • There will be technical debt and not all of it will ever get fixed
    • There will be things that don't make sense given the current situation but are impossible or impractical to change
  • Don't expect perfection from your process
    • There will be communication overhead and misunderstandings
    • There will be unclear and changing requirements
    • There will be situations where team members are blocking each other
    • There will be situations where team members unknowingly perform duplicate or conflicting work
    • There will be decisions that later turn out to be suboptimal because you didn't have the right info, knowledge, experience or priorities at the time

Imperfectionist mindset

Be humble

  • Realize that you are imperfect, just like everyone around you
    • See also the previous section
  • Be open to feedback from others, as it is likely that you can learn something from them or they have noticed something you missed
  • Embrace the fact that you can learn a lot from the people around you
    • There's no need to be the "smartest person in the room"

Own your mistakes

  • Since you are not perfect, it is expected that you make mistakes
    • Mistakes you make in specific situations do not imply that you are not good at what you do in general
    • It feels great to realize this and get comfortable admitting your mistakes
  • Rather than trying to hide your mistakes, admit them and give honest information about what happened
    • People who admit their mistakes come across as more confident, reliable and relatable than those who pretend to be perfect
    • Bonus points if you already have ideas on how to solve the problem
    • Bonus points if you can improve your process so the same mistake won't be able to happen again
  • Instead of ruminating about mistakes you have made, put that time and energy into fixing the situation or preventing the mistake from happening again
  • If someone in the team makes a mistake, take responsibility as a team
    • Naming the person who made a mistake doesn't solve anything, and gives the impression that the team likes to blame individuals instead of taking responsibility
    • Remember that everybody makes mistakes. If the process allowed for this mistake to happen, it was a matter of time before someone actually made the mistake, and it could easily have been someone else who made the mistake.
    • Solve the issue as a team and improve your process as a team

Focus on what you can control

  • A lot of things are out of your control, which means it's a waste of energy to stress out over them or try to change them
  • Instead, focus on what you can control
  • "Don’t get stuck thinking that you can’t do good work unless something you can’t control changes" (from Three Growth Strategies for Individual Contributors )

Focus on putting in the work rather than on the results

  • Worrying about results steals time and energy that you could otherwise spend on putting in the actual work that is needed to get the results
  • Reducing the pressure you put on yourself actually helps you perform your tasks more effectively
  • Focusing less on results doesn't prevent you from getting the results you want, it just takes away the anxiety about not getting those results
  • Note: This doesn't mean that there's no value in periodically evaluating whether your work generally gives you the kind of results you would expect to see. However, it does mean that there is no value in letting stress about results distract you from doing the work in the first place.

Prefer incremental improvement over sudden perfection

  • Focus on consistently making progress or adding value
  • Start from the way things actually are, not from the way you wish they were
  • Incremental improvement gives you early feedback on whether you're moving in the right direction
  • Incremental improvement is often a lot more practical than sudden huge changes
    • Example: First writing a working "first draft" of the code and then improving its readability can be a lot more effective than trying to write perfectly clean code immediately
      • "First make it work, then make it clean"
    • Example: When introducing stricter coding standards to an existing project, changing all the existing code is often not practical or justifiable. But, if you apply the new standards whenever you write new code or touch an existing piece of code, all parts of the codebase that are under active development will soon follow the new standards
  • Big goals are daunting. Instead, chop the work up into small steps and follow the process, focusing on one step at a time.
  • There is often a compounding where early progress makes future progress easier
    • Example: Successfully setting up basic automated linting makes it easy to add more strict/advanced rules later on
    • Example: When learning, properly understanding basic concepts makes it a lot easier to understand more advanced concepts later on
  • See also How to Be Great? Just Be Good, Repeatably

Consider going for imperfect action now instead of possibly perfect action in the future

  • Taking a good enough action means improvement, not taking action means no improvement
    • "Great is the enemy of good"
    • Good code shipped today is often better than perfect code shipped next week
  • Often, the experience you gain from taking action teaches you a lot more about what works well and what doesn't than just theorizing about what would be the best approach. See also Quantity Always Trumps Quality
    • For creative problem solving, it might help to separate the process of creation from the process of analyzing what you created and improving. "You can’t write and edit, or sculpt and polish, or make and analyze at the same time. If you do, the editor stops the creator. While you invent, don’t select. While you sketch, don’t inspect. While you write the first draft, don’t reflect." (source )
  • Definitely don't wait for perfect circumstances, as they will likely never come

Focus on solutions rather than problems

  • Software development is all about problem solving
    • Your real value is in delivering solutions
  • Often, problems don't even need to be solved in order to make progress despite them
    • A lot of problems are not showstoppers
    • In a lot of situations, a workaround or partial solution is enough
    • Sometimes, it even makes sense to simply ignore the problem
  • Rather than focusing on the problem, focus on finding possible solutions or at least paths that lead towards possible solutions
    • Problems that seem unfixable at first sight are likely to be fixable once you really think about it
  • Looking at the big picture helps to find solutions or workarounds that may not be obvious if you focus too closely on the problem
  • Note: All of this doesn't mean that you should start solving before you understand what the actual problem is!
  • Note: All of this doesn't mean that there is no value in identifying problems!
    • Typically, you need to identify a problem before you can solve it
    • It can be very valuable to identify the main problems that are limiting your success
    • Try to be a Finder, someone who identifies important problems and can also recognize if the team is solving the wrong problem because it's just a symptom of another more fundamental problem
    • However, once you've found a problem, start moving your focus to actually solving it rather than just getting stressed by its existence

Make success easier than failure

  • All humans tend to get lazy and take the easiest route
    • This is especially true if they're under some kind of time pressure
  • Use this to your advantage by making success easier than failure
    • Make it so easy to do the right thing that it would actually be more work to do the wrong thing
    • If you want to create substantial and persistent change in the way people do things, you need to make sure that the "right way" to do something is also the easiest way for people to achieve their goals. Instead of forcing people to do something, you need to make them want to do it. Otherwise, they will always find their way around it.
      • Making the "right way" easier is often about tooling, but training can also have a large impact
  • Example: productivity
    • Chop up your tasks until they're so small and well-defined that it's easier (and more fun) to start and complete them than to find excuses for avoiding them
  • Example: enforcing coding standards
    • Writing up a document with coding standards and then expecting the team to follow them through sheer discipline is not the ideal approach
    • Automated formatting checks and linting make it easy to recognize and fix deviations from the standards
    • Even better if everyone in the team has their IDE set up so all code is automatically formatted according to the standards whenever a file is saved
  • Example: making people write better PR descriptions
    • Can make success easier than failure by setting up a PR template where people just need to fill in the blanks
      • Can include description of changes, how to test things, ...
      • Can also include a checklist (written/adjusted relevant tests, ensured backwards API compatibility, ...) that we want developers to go through before committing their PR
  • Example: architectural governance
    • Want teams to do incremental rollouts instead of immediately applying new code to all instances or users? Foresee a deployment pipeline where that is the default behavior and where you need to jump through a few hoops to bypass the mechanism.
    • Want developers to respect certain boundaries in your modular monolith? Enforce the boundaries programmatically and require thorough reviewing of any changes to the enforced rules.

Resources