Code criticism: Context Matters
I work as a software developer consultant. This role often puts me in the midst of varied personalities and codebases. I’ve learned that approaching a new codebase requires caution and an open mind, akin to entering someone’s home for the first time; you wouldn’t immediately criticize their choice of decor.
A codebase is more than just lines of code; it tells a story. Delving into it, one can often see different personalities and thought processes, reflected in formatting choices, the presence or absence of tests, and other nuances. The code we write is meant to solve a myriad of problems, ranging from business to user-facing issues.
A memorable experience from a few years back illustrates this well.
A new hire, fresh to our team, scrutinized our codebase and questioned, “Why are you still using this old version of X?” My response, emphasizing practicality, was: “It works, it’s tested, and it generates revenue for the business.”
For me, this experience was eye-opening, revealing a common tendency among developers to gauge success by the novelty of technology, rather than the tangible outcomes or values their work brings. This wasn’t an isolated incident. Over time, I found myself defending numerous architectural decisions:
- “Why not use
std::accumulate
instead of for-loops for accumulating values?" - "Have you considered using
luxon
instead ofmoment
for date handling?" - "Why aren’t there more pure functions in this code?”
While I’m open to constructive feedback and embrace change, I believe in pragmatism. Rewriting functional software or making changes solely because “I wouldn’t do it this way” is not always the best course of action.
It’s crucial to remember that code is not just a set of instructions; it exists within a specific context. When the new hire criticized our use of older technology, they overlooked the constraints we were facing at the time - budget limitations, client requirements, and the need for a stable, reliable solution. Such context-awareness is often missing in hasty critiques, leading to the mistaken belief that the original developers should have known better.
Understanding the challenges and constraints the people before you faced does lead to more respectful and productive discussions. It’s about inquiring (gently) and understanding, rather than immediately jumping to conclusions.
I’ve come to value constructive criticism that is not just about highlighting flaws or proposing updates but is offered in a way that respects the original intent and acknowledges the existing constraints of the code. This involves weighing the practical implications of suggested changes and providing feedback that is both thoughtful and actionable.