When clean code becomes harmful
Is our industry’s obsession with clean code setting us back? #
I’ve been in the software industry for 15+ years now, and as time goes on, I feel like I’m becoming increasingly delusional. As a fellow developer, I have been brainwashed by our industry’s rhetoric to believe everything is about writing “clean code”. You know what I’m talking about: Talk is cheap; show me the code!
We are not aware, but the problem starts when we are junior developers. We are eager to learn and often ask our senior peers for advice. We ask things like: What books do you recommend? Two of the most recommended books are Clean Code and The Pragmatic Programmer. These are both excellent books, and I believe everybody should read them. Both books share some of the same advice and try to teach us how to write better code and become better professionals. However, they have very different focus areas.
Among many other pieces of advice, Clean Code focuses on avoiding duplication, descriptively naming variables, keeping code formatting consistent, keeping functions small and ensuring that they only do one thing.
On the other hand, The Pragmatic Programmer focuses on things like building pragmatic teams, teaching us that our goal as developers should be to delight users and that it is not possible to write perfect software.
After reading both books, we return to work eager to apply our new knowledge. The problem is that the advice shared by Clean Code is much less open to debate and more accessible to put into practice than that shared by The Pragmatic Programmer. In my humble opinion, the advice shared by The Pragmatic Programmer is much deeper and meaningful.
We (Junior or Senior developers) can all identify and point out when one of our team members tries to merge a “God Class” (a class that is way too large and do too many things). However, trying to decide whether a piece of software is good enough or not can turn out to be the debate of the century.
I have been trying to find out if I’m the only one feeling this way by reading online recommendations about both books. I have found a Reddit post in which someone asks which book is better. Here are two of the comments that I would like to break down:
I recommend the pragmatic programmer (first). It is an easier read and contains more about a software development career in general rather than just being about code.
The first recommendation seems to reinforce the idea of The Pragmatic Programmer‘s content being much deeper (“software development career in general”) than Clean Code (“just being about code”).
I preferred clean code as it is more about the principles of what makes a good engineer. I have read the pragmatic programmer but didn’t feel it really added anything to my skills.
I think the pragmatic programmer will show you patterns to use, and various solutions, while clean code will be about professionalism.
So if you want self-improvement and self-exercise, then get clean code. If you need help with patterns and solutions, then pragmatic.
The second recommendation resonates with my feeling that the The Pragmatic Programmer is less actionable. The reader highlights how “the principles of what makes a good engineer” felt useless (“it really added anything to my skills”). On the other hand, the reader could “self-improve” and “self-exercise” using the “professionalism” advice contained in Clean Code.
We don’t realise it but have an unconscious bias towards prioritising advice that feels more actionable and easier to apply. The problem with this bias is that as time goes by, we focus more and more on the advice provided by Clean Code and less and less on the advice provided by The Pragmatic Programmer. Over time, developers focus more on code-related issues and less on other kinds of problems. When things are not going well, we tend to look for causes in the code instead of somewhere else.
Note: Within the code itself, we are more likely to identify and point out issues that are more obvious and actionable such as formatting issues, instead of API semantic issues. Our brain is biased toward inverting the Code Review Pyramid. For example, we are very likely to notice code repeating and try to enforce the Don’t repeat yourself (DRY) principle, while we are much more unlikely to notice a wrong abstraction. This fact makes us likely to introduce the introduction and the wrong abstraction as a solution to a DRY problem without being aware of our actions. The problem is that the wrong abstraction is much more expensive than “duplication is cheaper than the wrong abstraction”.
During the rest of this post, I will refer to this kind of bias (in the context of our industry) as “the code delusion”.
Note: This bias towards actionable advice is noticeable beyond our code and influences our processes and tools. For example, many organisations try to become more agile and adopt agile practices such as Scrum. They soon become obsessed with the Scrum rituals (Standup, Sprint planning…). This obsession is understandable because rituals are very actionable. The problem is that performing rituals is not what makes an organisation agile. The Agile manifesto mentions almost nothing about rituals.
You might think this is not your problem because maybe you have not read those books, but I guarantee you that you are impacted by this bias daily. It doesn’t matter because this bias is universal. I’m just using the books as an example; maybe you got your knowledge from a more senior colleague or an online course. The code delusion still applies to you.
What is the damage caused by the code delusion? #
When developing a software product, many factors influence whether our product (and ultimately our organisation) will fail or succeed. The way I see it; these factors can be grouped as follows:
- Product = UX + Feature Set + Value Preposition + Code
- Market = Undeserved needs + Target customer
- Culture = Mission + Vision + Processes + Tools
Since day one, my industry has brainwashed me to believe that code quality sets great developers apart, but as I gained experience, I increasingly realised how delusional this idea is. Over time, I have become more aware that code-related issues should be the least of my concerns. The way I see it today, almost everything in the list above trumps code. For example, I believe that UX is more important than code or that Processes and Tools are more critical than code.
The word “delusion” has the following meaning:
an idiosyncratic belief or impression maintained despite being contradicted by reality or rational argument
So what is the meaning of code delusion? Let’s break down this definition. A “delusion” is a mode of behaviour or way of thought. In the context of the code delusion, this way of behaviour is the developer’s bias towards “clean code”. We believe that when things go right or wrong, the cause must be code-related. In my opinion, this belief is contradicted by reality. Code quality is only a very small factor in the destiny of an organisation.
A few years ago, Google published a study titled The five keys to a successful Google team. The study highlighted the following:
There are five key dynamics that set successful teams apart from other teams at Google:
- Psychological safety: Can we take risks on this team without feeling insecure or embarrassed?
- Dependability: Can we count on each other to do high-quality work on time?
- Structure & clarity: Are goals, roles, and execution plans on our team clear?
- Meaning of work: Are we working on something that is personally important for each of us?
- Impact of work: Do we fundamentally believe that the work we’re doing matters?
Psychological safety was far and away the most important of the five dynamics we found – it’s the underpinning of the other four.
Mi personal experience is that psychological safety is compromised more in teams with a culture where code quality is valued more than everything else. For example, organisations that tolerate “Brilliant jerks”. Brilliant jerks are high-performance individuals capable of producing high-quality code in no time. However, these individuals have very weak emotional intelligence skills. Brilliant jerks make other team members feel like they are a piece of shit every time they make a coding mistake. Even when the reality is that the mistake might have zero impact on the overall company performance.
Time to re-evaluate ourselves? #
Our industry believes that code trumps everything else “despite being contradicted by reality or rational argument”. This way of thought is so powerful that it goes beyond the development team. For example, an organisation can decide that investing in the development team is a higher priority than investing in the UX team or that it should design interviews to focus on assessing technical skills over emotional intelligence.
I’m tired of finding myself being part of teams that are deeply frustrated for reasons such as:
- Our tech stack is too old.
- Our standup meetings are taking too long.
- Our test coverage is too low.
- Someone is trying to use spaces instead of tabs.
Instead of reasons such as:
- We don’t invest enough in the UX team.
- There are too many tickets are WIP.
- We don’t do A/B testing.
- We don’t talk enough to our users.
I have witnessed many teams of experienced developers with a virtually infinite budget failing. On the other hand, some of the most remarkable success stories I witnessed are the result of the work of a bunch of graduates with almost no previous experience in a startup with practically no resources. The causes of this phenomenon are evident in my mind. In big corporations, the developers don’t have to worry about the next paycheck, so they spend much time discussing code issues (e.g. a 6 month long refactoring). While in the startups, the mentality is “ship it or die”.
I’m a developer, and I produce code daily; accepting that good writing code is not as essential as I was brainwashed to believe is a hard pill to swallow, but I must accept reality. Aiming for code perfection in software is not only unrealistic but is counterproductive. It leads to all sorts of problems: premature optimisations, feature overload and over-engineering.
Writing clean code is not what makes a developer a great developer. A great developer should:
- Be obsessed with delivering customer value.
- Have a good judgement for reaching compromises between code quality and customer value.
- Tries to write clean code but knows when to stop pursuing it.
- Knows that not all parts of a solution are equally critical and will only pursue clean code when is worth it. For example, interfaces are much more important than implementations. If you get interfaces right, replacing implementations over time should not be a problem.
The code delusion often makes us focus on things that are often meaningless and a total waste of time. I’m not advocating to write spaghetti code but my feeling is that using our energy to focus on engineering excellence over user satisfaction is contributing to a large portion of our industry feeling miserable. We should aim to write good enough software while remembering that developers don’t get to decide when software is good enough: Users do.
Note: The title of this post is a reference 1968 letter by Edsger Dijkstra published as “Go To Statement Considered Harmful”.