It starts with a sort of blissful ignorance. We write code oblivious to the consequences, unhindered by the necessity of receiving feedback about this code, and to the need for feedback on what we’ve done. We naively construct a tower with what we find here and there. When the tower shakes, we suddenly become extra careful and take that extra bit longer on each small portion of code, all the while buckling to pressure from our clients and managers.
The tower crumbles; we rebuild hastily. There’s no time for quality assurance because there are too many issues to resolve that we didn’t anticipate, issues we didn’t anticipate because we have a weakness in our quality practices, a weakness we have because we don’t have time for quality assurance. We lose our calm and react irrationally, in a precipitous, disorganized way.
Unable to see what would be needed, or even observe what currently works well, we leap to imaginary false conclusions. We research whether better estimates could work and what better requirements would be, instead of looking into what’s actually slowing us down the most. We develop a sort of bad faith, which serves to explain everything. We are on the defensive.
The whole time the code is slowly but surely sinking into entropy. Headlong rush to keep going.
What would be needed to fix this problem? The more we wait, the more the cost of counter-measures increases and the more the work weighs on us. Want to see something that causes progressive disorganization? Watch the noodle of chargers and cords behind the desk that grows and tangles with each branch and merge. An utter mess.
The problem only gets worse with time. We have no clue what could reverse the slide towards entropy. The problem then turns into a problem of results, credibility, and defensiveness, instead of a problem of quality. It becomes a debate, a conflict, a battle.
Someone says: « If the code could talk, what would it say? »
So we try to make the code talk, using tools that reveal the extent of the damage and calculate the technical debt. At least we’re doing something. Like at global gatherings on climate change, we reflect on the consequences when we don’t even know how to prevent the causes. And indeed, each cause is a tiny detail in the larger context. Each cause would require that we learn a new trick – the exact trick that would prevent future failures.
The code of a program, such as it is presented in the books of the Sacred Art of Coding, is like a cathedral of logic. But for the newbie, newly recruited into this ‘TMA’ team, the code is a quagmire. It is a cacophony of perverse effects, of unexpected consequences in which the composite effect of each rashly made decision, of each addition done in haste, blindly, multiplies into a logical nuclear bomb.
The program crashes – a massive jumble of intertwined causes.
The program fails on a test, which prevents another test, which would have revealed the presence of a gap between what was expected and what was produced; and that gap would have slowly but surely led to the detection of a logical error in the calculation code; and that error, had it been discussed between the testers and the developers, would have shown certain rules are not shared, due to differing interpretations because the two teams don’t see the product in the same way.
At each step, there is a fuse. What do you think a professional team of landmine defusers would do? Exactly. It’s exactly the opposite of what a team of developers would do. No one takes the time to stand back far enough to see all the detail of what exists. Instead, a developer is busy repairing the program, while others are commenting on the situation, or doing busy work while waiting for a decision from management.
By my logic, the response to an incident would go:
‘Let’s take the time to do rigorous root-cause analysis to find out what happened, without placing blame and without any rash decision-making, and let’s find what countermeasures we can take so that we can avoid similar incidents in the future.’
… my colleagues however, are mystified by my logic:
« That doesn’t look like something we could do without spending at least 4 hours!! »
« It would be more worthwhile to… »
« In any case… »
« Yes, but… »‘
and then the manager interrupts because the client is furious on the other end of the line: « Fix it and re-deploy! »
We live in complex times and we often hear that ‘software is eating the world’. Complexity eats the code too. This world, the one in which we take on, dismantle, take up again, and re-launch software projects surfs on all of that complexity.
The way things are going, we will always need ‘all-terrain’ teams.
How can I achieve ‘all-terrain’ if I can’t even drive the jeep in the parking lot? I drive 20 miles, and wham! A dumb accident.
We offer all kinds of excuses: ‘we should have…’, we list ‘best practices’, we make presentations and prescribe ‘transformations’. But we know perfectly well – since we would be incapable of restoring a Louis XVI armchair, performing a sonata, or dispensing care after a heart attack at the drop of a hat – we know perfectly well:
That is to say that it takes time for basic practices to become habits, for knowledge to be sufficiently anchored to distinguish a professional from a passionate amateur.
Suggesting a team change its habits in the middle of a project in crisis? At an accident scene, we certainly have more convincing arguments for a while. Change is hard enough even when things are going well, despite our conviction that there are good reasons for such change.
Now is not the time to learn the basic practices.
If the code could speak, what would it say? Let’s give it a voice:
Here I say things like this, and there I say things like that. It’s just that way.
I repeat myself so much that I could kill your attention, your interest, your enthusiasm the whole page down.
It’s unpronounceable, twisted and complicated, but wait – there’s more!
What do you mean: ‘does it work?’ Would you even be here if it didn’t work? Come on!
You can show your disgust, but such is life.
Just try to change this method. Good luck! I’ve cracked tougher nuts than you.
For me to work correctly and be reasonably maintainable, you would have had to put in twenty times more work. Did you hear that? Twenty times!
Forget your dreams of simplicity and efficiency. In the end, you are neither artist, scientist, thinker, nor engineer. You are an all-terrain ninja developer.
We give in to just managing delays. We’ll fix the technical debt too. We’ll mend the relationship with the customer. We have to manage everything because nothing can be done independently. There is only trudging along, because there is no solution. There’s no way to make a late project such that it is no longer late. We know, but we will still go forward. Thirty six months of clean code that passes testing is already a highly delicate construct that requires daily attention (ask around), so just imagine 36 months of code written on the fly. We’ll be clearing landmines for years to come. It is, as I said before, a nuclear logic bomb.
Yet… Could this possibly be the moment to at least pause and reflect? What if it was time for us to start changing the way we work?