Browsing Hacker News recently, I stumbled across this blog post arguing the position that coding standards are not only unnecessary, but may actually end up causing more problems than they solve. I intended to write a response during my lunch break, but then things happened, and I forgot to do it.
In many cases I am inclined to agree that the absence of a ‘one true way’ means that people are free to come up with exciting, innovative, new ways to accomplish things. However, Richard Roger glossed over perhaps the most glaringly obvious reason about why coding standards matter, arguing that standards are bad because:
…you get to duck responsibility. Everybody on the team does. We followed the rules! You failed. Yes, but we followed the rules! Well in that case, here’s another project…
Responsibility is the reason why we need coding standards. Responsibility not only to the development team and our company – but to the customers and users who in many cases base their entire livelihood around our code.
Software gets written for one of two reasons:
The first reason is that you had a great idea, and you just need to show the world. You develop your idea in isolation, or with a small team, and you have no users. You have no worries until things start to get exciting and the world is flooding your inbox demanding new features. You get a million users in a month and then suddenly you realise something: you’re not the genius you thought you were.
Your software doesn’t scale. Adding a new feature takes twice as long as it should. Your app crashes when people try to login with a Chinese username (assuming you’ve internationalised your app in the first place, right?). It’s slow, it’s ugly, and you know – deep down – that you can do better. The problem is this: you have no responsibility to anybody but yourself – and this industry demands that you ship early and ship often. Beat the competition, even with a buggy first release – and provided it’s not too bad, you’ll get people’s interest. We live in fickle times, and not shipping until something is ‘just right’ is basically the same as not shipping at all. Coding standards will almost certainly be ignored in this kind of high-pressure environment. You need to get things done fast, or you’re wasting your time. Ignoring standards is fine, you tell yourself, because it doesn’t matter whether your code sucks or not – nobody but you or the other three members of your team are ever going to read it, and if users don’t like your product anyway, then you have no responsibility to make sure they’re getting the best. The only thing that users are going to talk about is whether the product works or not – not whether it’s scalable or modular or the code is nicely structured and commented. You keep telling yourself that it’s an irrelevant detail that can be sorted out tomorrow. Well, you all know this already: tomorrow never comes.
The second reason software gets developed is that somebody wants or needs it, and approaches you or the company you work for to build it. This is why most software gets written – because frankly, that’s where the reliable money is. This is the ‘invisible’ side of the software industry that people rarely get excited about because it’s (mostly) boring, repetitive work. You will get no awards. You won’t become a millionaire. It’s not sexy, it’s not cool, and most of the time you’ve already written something incredibly similar before.
This is the side of the industry that I work in – and it’s most likely the side of the industry that you work in, too. It’s stable, for the most part, but there’s very little I can point to that I’ve worked on that is going to get anybody waving a pile of cash in my face. Of course I want to change this. I want to be a rock-star (who doesn’t?) who invents the next big thing and retires to my private island while my own personal fleet of jets drops payloads of money directly into my bank. In the mean-time, however – I have bills to pay, because I’m a Real Live Person and my life is ordinary. And, like most ordinary people, I rely on certain things in order to pay those bills. I rely on the fact that my car starts every morning. For a whole two months very recently, it didn’t, and I ended up needing to spend a whole load of money to get a new one. That was painful. I also rely on the roads to get me to work. When I get to work, I rely on the power supply so I can actually do my job. I rely on the internet connection working for so many different reasons that listing them all would be a pointless exercise: we all rely on it these days. I rely on my web browser going where I tell it to go. I rely on my operating system keeping track of my files, and when something’s going wrong, I rely on the fact that there’ll be an update to fix it. In order to fix it, I am relying on the fact that the authors have written their software in a way that makes it easy to fix. This is my livelihood at stake here – if I can’t do my job effectively because I can’t rely on the software I use, then my company won’t earn as much money. If my company doesn’t earn money, then they can’t pay me. If they can’t pay me, then I need to find another job or suffer the consequences of not being able to pay my bills. If any of those things don’t work, and it turns out that they can’t be fixed, because “woops, we don’t follow any standards!”, then I’m screwed.
This is the point: You and I come with dependencies. I can’t do my job if certain dependencies aren’t met – and if I’m paying money for something that I am going to rely on, then I would expect that the people who are satisfying those dependencies for me would do their jobs properly. And this is why coding standards are good for our industry as a whole: responsibility. We as software developers are creating products that people often rely on in order to pay their bills. That website you developed for that small business doesn’t just go away once you’ve finished the project. Your client is relying on it so that they can run their business. That tiny, boring piece of middle-ware you wrote for that mega-corporation in order to transfer those very specific sets of files to a very specific location at a specific time of night is saving them hundreds of man-hours per week.
You may not personally care about whether that website’s shopping cart can be rapidly swapped out for something else, but your customer does.
You may not care about whether that file-transfer utility is easy to update to add new source or destination locations, but your customer does.
If you’re not writing software that makes it easy for customers to come back to you with ideas for changes, then you’re failing in your responsibilities.
Imagine if you bought a new car and it took a week to replace a tyre because no standards governed its manufacturing. Imagine if you called up the manufacturer querying this obviously ridiculous situation, and they told you that they never thought you’d need to do that, and the car just isn’t built to allow such a change to be made easily. You’d (quite rightfully) tell them that you’d be taking your business elsewhere – because a week to replace a tyre is just insane. And that would also be a massive pain for you, because now you need to buy a new car.
“That’s a stupid analogy”, I hear you saying, “We always get our requirements up front. You should have told the manufacturer that you’d need to replace your tyres at some point and they would have made it easy to do. It’s your own fault!”
Do you really get all your requirements up front? Honestly? Or do you get a month down the line and then the customer calls you up and says “Oh, by the way – we also need this software to do things X, Y & Z”?
If you have a set of standards that you abide by, then you say to the customer, “Well, we didn’t know that, but it’s no problem, it’ll just cost a bit more.” And then you all shake hands, and you implement the new features quickly because your existing code is nicely organised and structured and modular, and the customer pays you and you stay in touch forever and send each other Christmas cards every year.
Or, in the world where we decide to abandon coding standards, this happens:
- The customer asks you to implement something you didn’t anticipate.
- You go to look at your code, and realise that in order to add the new features, you need to significantly re-work your code-base.
- You work out the cost of the changes, and the customer laughs in your face and walks away.
Richard Rodger’s post talks about coding standards as if he’s tried to implement them and then they’ve just been ignored.
…control feels good. It’s a comfortable hole in the sand. But you can’t tell coders what to do. Cats don’t herd.
This is the problem – not the fact that the standards exist in the first place. If you’re going to implement a standard at all, then you need to enforce it. Coding standards alone are not going to magically produce wonderful, extensible, clean code – but they can certainly help. A good set of standards will be based on experience. They will be discussed, and agreed, by people who know what they’re talking about – and they will be enforced by people with the authority to crack the whip when it needs to be done. Standards alone are useless – without enforcement, they’re just guidelines. The reason developers can’t be told what to do is that every developer thinks he’s the smartest, best developer in the world. That’s why you shouldn’t just be telling them what to do, you should be convincing them that doing it your way is the right thing to do. Your standards should be justifiable, not just ‘the law’. If they can convince you that you’re wrong, and they’re right – then you should acknowledge that. But if they can’t convince you – if they just carry on doing the wrong thing time after time, then you need to assert your authority. Take control, and explain why the standards exist.
Our industry romanticises the renegades – the people who do it their own way and damn everyone else.
We need to stop this. Desperately. Not everybody is special. Not everybody is right. Not everybody is smart.
We read blog posts every day which tell us how smart we all are, and about how managers don’t have a clue, and standards are stupid because we know what we’re doing.
What if I was to tell you that you’re more than likely just a regular person, just like the rest of us? How many times have you come back to your own code after a month away and cringed at how bad it is? You may not be stupid, but you make stupid mistakes. You need to be controlled, because you’re a goddamn liability. Everything you touch carries a degree of risk, because ultimately this software you’re writing is going out to a customer who is trusting in you to do a good job and not fuck it up. We have standards to help mitigate this risk. We learn from experience. We listen to our peers. We act responsibly. If I work with you: I’m relying on you to do a good job and help make this project a success so we both get paid at the end of the month. Do your due diligence.
I know Richard is not advocating the abandonment of any sense of quality control – but I do think he’s dangerously conflating two different things. The first is the idea of best practices; that your code needs to be structured in a certain way in order to allow for easy maintenance, extension, and hassle-free bug fixes. These are just things that good developers should be doing anyway: if you’re hiring developers that don’t already do these things, then you’re probably in more trouble than you think.
The second idea is that of ‘style guidelines’. I am inclined to agree that enforcing a strict standard on things like line-length, position of curly braces, and naming conventions is more hassle than it’s worth. I would recommend that development teams keep their code style consistent, but I’m not sure it really matters much in the long-run. It’s nice when all of your method names look the same, and your variable names are clear, and your curly braces are all in predictable places – but it doesn’t change the fact that if the code itself is garbage, then you can groom and style your code all you like: it’s not going to make it any better.
To me, style guidelines don’t matter so much provided the other considerations are accounted for. I have a responsibility to make sure that the code I produce for my company is clean, easily maintainable, and can be extended and modified with minimum fuss. Additionally, I have a responsibility to customers to ensure that if we screw up – if they find a bug that we missed – that we can fix it quickly and with minimum disruption. Every day I build software that people rely on. If our customers knew that we followed Richard’s advice and just threw out our coding standards – I don’t believe we’d have customers for much longer.
Customers can spend hundreds of thousands of pounds on software that my company produces – and it’s part of my responsibility to make sure that the code is good. I have a responsibility to my company to extract maximum value out of everything we do. This means that code needs to be testable. It needs to be re-usable. It needs to be extensible. These things are good for the company, and they’re good for customers. It reduces costs overall – if we’ve developed some code that can be re-used in a new project, then we don’t need to charge as much as we would if we needed to write the same code over again. If the code is easy to modify, then customers can approach us with confidence when they need changes. There’s less discrepancy between our estimates and our actuals. Throwing standards out means that we get none of these benefits. If the code’s a mess, it’s impossible to modify and maintain properly. If it’s not modular, then we can’t make changes or add new features as easily. If it’s poorly structured, then ramp-up time for new developers increases massively.
“It should never get to that stage – that’s why you have code review!” you shout. Well, what is code review, if not a forum for discussing whether or not the code meets some pre-determined standards? If you can’t enforce those standards, then you can’t control the code – and if you can’t control the code, then you’re going to struggle to meet your responsibilities to both your company and your customers.
I expect everyone to write good clean code. You decide what that means.
Then why are you telling people to discard coding standards? If you have expectations about “good clean code”, then you have standards. You just haven’t written them down.
You decide if you can sleep at night with random code layouts and inconsistent variable names. But you know what, maybe they just don’t matter for a 100 line node.js mini-server that only does one thing. You decide.
Maybe they don’t matter right now – but what if the customer decides that it needs to do two things in a month’s time? This attitude of ‘good enough for now’ is unfortunately pervasive throughout our industry, and in my opinion, it’s poisonous. If one person on the team has this attitude, then it rubs off on the other members of the team until you end up with a bunch of people who optimise for time at the expense of quality. Reversing this attitude is a monumental task: how do you convince people that ‘good enough’ is not good enough, when all of the rock-stars are telling them it is? The boring software is what makes our modern world function – and people rely on it. You may not think that your current project is particularly exciting – but what does your customer think of it? If it’s going to save them time and money, then it’s probably one of the most important things in their professional lives right now. If you have any sense of professional pride – you’ll want to do a good job - the best job – and you’ll want to make your customers happy.
So coding standards serve an important purpose: they give your customers confidence that you’re going to meet your responsibilities. You don’t just throw a bunch of random code together: you think about problems, you minimise costs, and you maximise value for both the customer and yourself.
Whether your coding standards live in your team leader’s head; whether they’re on a company Wiki or in a PDF document – it’s important to have them. You can’t objectively assess every line of code on its own merits just because ‘standards limit imagination’ or whatever nonsense you just read online. The reality is this: you have a responsibility to yourself, to your colleagues, to your company, and to your customers. Standards are about more than just enforcing some ridiculous rules upon your development team. If we aren’t seriously trying to meet our responsibilities, then what good are we? If our customers can’t trust us to take their projects seriously: to enforce good practices and standards across our work, then why in the world should they hire us?
But how is the master craftsman judged? By results, only.
Wrong. If you’re buying something just because it looks flashy and cool, then you’re going to have problems sooner or later. The people who buy software often have no idea about what’s going on beneath the surface. It’s not like assessing the build quality of a new table or chair. You can’t reliably determine whether software is well written, robust, or easily maintainable simply by looking at its GUI. You can’t give the login screen a good smack to see if the legs fall off.
The master craftsman is judged not only by the obvious – the look, feel & finish – but by all of the implications that such a title holds. A master craftsman is reliable – he understands how to make things that will last, that will hold up when used in unforeseen ways, and will survive bumps and scrapes for years to come. This doesn’t just happen accidentally – it’s intentional. Holding yourself to a set of standards means that your software will survive and your customers can rely on it. You probably already hold yourself to some personal standards – so what’s wrong with a team holding themselves to a set of standards, too? Whether you write them down, or you just enforce them during development and review, it doesn’t particularly matter.
This isn’t to say that standards need to be set in stone and enforced rigorously at the expense of everything else. Sometimes, there are excellent reasons for not following the standards. Sometimes its performance related, sometimes it’s because you discovered some quirk in a third-party system. Sometimes it’s just because your standard is stupid. I believe that standards should evolve over time. They should be based on experience – and more importantly, they should be argued about. If your standards don’t cause some kind of conflict initially, then they’re probably pointless. A standard way of handling and logging errors is not stupid: it’s so obviously ‘the right thing to do’ that most people don’t even think about it. What that standard should be is what causes conflicts – and this is why you should discuss your standards and work them out properly. A standard doesn’t have to be dictatorial – the thing that matters is that once those standards are agreed, they’re enforced. How you enforce them is up to you – you don’t need to go firing people for ignoring the standards so long as one of the following happens:
- They justify why they’ve ignored the standards and you allow the exception.
- You explain why the standard exists and get them to change their code.
You should allow developers to question your standards. If you can’t justify your standards, then you’re just making up rules for the sake of it. Stop that. You should allow developers to suggest changes to the standards, too – because like Richard says:
Starting with the principle that our coders are really smart. That does work.
By and large, you don’t get to be a developer in the first place if you don’t have some degree of intelligence. You should be able to justify why you think something is a good idea or a bad idea. If you work somewhere that is enforcing a bad standard, then speak up. If the standard is being used as a stick to beat developers around the head – then get out while you still can. If, however, the standard is being used as it should be: to ensure that you meet your responsibilities, then perhaps you’ll find that it’s more negotiable than you think.
Most developers want to do a good job, and most developers will agree that doing X a certain way is a good idea. It makes sense, then, to agree that every time X is needed, you’ll do it the way that you’ve all found to be the best way. If somebody does it a different way, then surely they should be able to justify why they’re ignoring the experience of everyone else? In what industry other than software development would this not be questioned?
Take pride in your work: decide on what you want your code to look like, and then enforce it. It’s not realistic to think that enforcing standards will mean you never produce bugs, or that your projects will never fail – but you’ll be saving yourself time and effort when it comes to fixing those bugs or salvaging what you can from a project that never quite got finished. On top of that – you’ll make your customers love you.
Yes, developers are smart. Yes, you should be able to trust your developers to do the right thing. But what happens when they mess up? Programmers are people – they will mess things up sooner or later.
You’re not writing the code. Why don’t you trust them? No, that’s not the right question. They will still mess up. Why are you making a bigger mess by telling them what to do?
That’s not the point. It’s not about telling developers how to do their job – it’s about ensuring that when you stamp your name on something; when you give something your seal of approval and say to your customers “This is our best work, this will meet your requirements, and you can rely on us.”, that you’re being honest. Why should a customer trust you if you don’t hold yourself to a set of standards that you believe enable good software to be written? How do you deal with problems when you have no standards and some component is implemented in a bad way? You have nothing to point to so that you can say ‘this is what we should have done’. You didn’t do your job properly. You weren’t being responsible.
Be responsible – people are relying on you.