Excellence is a habit

In martial arts training, you spend a lot of time repeating certain movements, sequences, and reactions over and over again. When learning a defense, one partner often executes a predetermined attack, and the other one practices the defensive technique. Usually (hopefully!) your training partner is not really trying to hurt you. Also, very few people would be able to go full-throttle for a whole training session, even if they wanted to. As a consequence, practice is mostly done at some level of reduced force.

Now, the thing is, deflecting a blow dealt by someone who isn't really trying to hurt you and who is also conserving strength is relatively easy. You don't really need much in the way of technique for that. Unfortunately, this means that it is very easy to become negligent. You don't step as far aside as you should because you don't feel the need. After a few repetitions, your partner starts to punch slightly to one side because your blocking technique is going to push the arm over there anyway, right? And your technique gets sloppy without you noticing because, well, it seems to work, doesn't it? You are standing at the wrong angle but it doesn't matter because your partner is focusing on the (slightly off) punch and doesn't realize you are in reach of their other arm now. And neither do you. Let's call this way of training “sloppy mode”.

This is all well and good as long as you keep training in this way. But what happens when we add pressure, e.g., with a belt examination? I have trained with a lot of youths who have confidently told me, “In the examination, I'll try harder/step farther/block better!”

Let me tell you what usually happens. When the pressure is on, people do what they have always done, except sloppier and with more force. Will they hit harder? Yes, they probably will. Will they block with more force? Yes, they probably will. Will they find the correct distance if they didn't before? No, they won't. Will they block more accurately? No way! Will they position themselves better? Forget it! Will they fumble, forget steps, miss their aim? Depends on how much they have practiced. I repeat: Under pressure, people do what they have always done, except sloppier and with more force.

This is because under pressure, there is no time to think, so you fall back to habits. Your mind goes blank, and your body takes over and performs the movements it remembers. You don't think, “Oh, wait! This time, I wanted to do it differently!” Instead, you think, “Oh, shit!” Or, “What am I doing?” Or you don't think at all. If you stop to think, you are already down. When the pressure is on, you don't think. You rely on habit.

The whole point of training is building habits that work well in the kind of situation you are training for. This means that you must strive to execute your defense flawlessly, performing the correct movements while maintaining good form each and every time. Even if your partner's attacks are lackluster. Even if you could – in the training situation – defend yourself by just waving your arms in front of your face. And even if you yourself are tired. You may train at a lower energy level. Energy will increase under pressure. But you must not train sloppily! If you build a habit of sloppiness, you will be even more sloppy when it matters – when your are under pressure.

If, however, you make a habit of moving correctly – even when it is not strictly needed – you can rely on this habit to defend yourself when it matters.

Or, in other words, you build excellence by putting in the effort when it doesn't matter – because excellence is a habit.

What does any of this have to do with software development? Well, have you ever thought to yourself, “Do I really need a unit test here? Ah, no, it's obviously correct.” Or, “This method looks long. Maybe I should split it? … Naw, too much work, and it's not too bad.” Or, “Why is the linter complaining? Stupid distraction! I'll just silence the warning for now.” Or maybe you didn't think too hard about corner cases because it got too complicated and when are those going to occur anyway?

Sometimes you just want to get something done and gloss over the details. And it works. You get it done and move on. Often, you can get away with skimping on code quality in the short term because there are no immediate repercussions. And implementing the happy path gets you quite far without thinking too hard. And everyone is happy, right? Because, when you get down to it, most code isn't that critical. So what if it isn't as clean as it could be, not as robust as it could be, not as [insert your favourite quality here] as it could be?

To my mind, this is akin to practicing martial arts in sloppy mode. Yes, it works … for now. There are no immediately visible negative consequences. And it is less work. It may even feel more efficient. Writing one less “useless” unit test. Not getting hung up on finding the perfect class name. Copying and pasting instead of extracting common logic because it's faster in the short term. Coding the parts users want, not getting distracted by trivialities. Getting things done!

But – and this is a big BUT – what happens when it does matter? When bugs creep in because of untested “obviously correct” code? A real example: in one of my past projects, I reviewed a pull request by a colleague and noted there was no test for a certain class he had changed. He replied that the class was just there for uniformity with the rest of the implementation and was only passing through calls to a delegate. Such a class was not worth the effort of a unit test in his view. The class did have one if statement, however – and as it turned out later, he had erroneously reversed the condition. With a unit test, he would have noticed this himself – and earlier – saving us time.

What if many small “insignificant” slow-downs add up to a performance nightmare? I once spent a lot of time speeding up a performance-sensitive application by 250%, by “just” eliminating unnecessary copying of data structures.

What if the edge cases you didn't care enough about to handle correctly suddenly start to occur en masse in production and lose you business? When I was responsible for a payment service, we were seeing errors in the logs that indicated there was a problem with customers who had not been active for a year or longer. At first, we thought it was just an edge case that was badly handled, but in reality, this edge case was occurring at a much higher rate than we would have thought, causing payment problems for real customers.

If you program in sloppy mode, your system may work as long as nothing untoward happens. If you have few users and your software is uncritical, you can fix issues as they come up with little ill effects. But it all gets much worse when we add pressure. Pressure on the system or pressure on you.

Increasing load, increasing transaction volume, increasing numbers of users put pressure on the system. Things are more likely to break when they are not built well. Performance problems manifest when the load increases. If you have a million customers, even an edge case that only occurs 0.1% of the time will affect 1000 customers. In software that is under active development, each over-complication, each misnamed entity, each code duplication increases the chances of defects due to misunderstandings or oversights, and also increases the effort required for even minor changes. This is when you need engineering excellence. Or when you notice the lack of it. And when you do, it is already too late. You would have to have built in the quality before – while it wasn't yet needed.

And then there is pressure on you: when an important deadline looms, when you need to incorporate new features faster than your competitors, when you need to scale up quickly, when the excrement hits the ventilator in production and you need a fix now, this puts pressure on you. And under pressure, you do what you always do, except sloppier and with more swearing.

If you want high quality under these circumstances, you need to have built up excellence … before. Because if you haven't developed the habit of programming with high quality while it wasn't strictly necessary, why do you think you will be able to do so now? You build excellence – the habit of excellence – by putting in the effort when it doesn't matter. And you reap its benefits when it does.

This should have been the end of my post, but between finishing and publishing it, I went to my Aikido dojo, and my teacher said something that fits perfectly. He was admonishing us to perform big movements and not leave out intermediate steps, saying,

“If it's there, you can always leave it out later. If nothing's there, you can't leave anything out.“

Think about that.

This post is part of my series on martial arts and software development.