How We Get Coding Standards Wrong

The other day, I sat in on a meeting where a large-ish group was discussing “standards” for their particular area of software development. I have the word standards in quotes because, by design, there wasn’t a clear definition as to what sorts of standards they would be; it was an open-ended exercise. The standard could cover anything from variable casing to development practices and principles to holistic approaches. When asked for my input, I was sort of bemused by the process, and I said that I didn’t really have much in the way of an answer. I declined to elaborate much more on that since I wasn’t interested in derailing the meeting in any way, but it did get me to thinking about why the exercise seemed sort of futile to me.

I generally have a natural leeriness when it comes to coding and development standards and especially activities designed to flesh those out, and in this post I’d like to explore why. It isn’t that I don’t believe standards should exist or that I believe they aren’t important. It’s just that I think we frequently miss the point and create standards out of some sense that it’s The Right Thing, and thus create standards that are pointless or even detrimental.

Standards by Committee Anti-Pattern

One problem with defining standards in a group setting is that any group containing some socially savvy people is going to gravitate toward diplomacy. Contentious and arbitrary subjects (so-called “religious wars”) like camel case versus Pascal case or where the bracket after a function goes will be avoided in favor or things upon which a consensus may be reached. But think about what’s actually happening–everyone’s agreeing that the things that everyone already does should be standardized. This is a fairly vacuous exercise in bureaucracy, useful only in the hypothetical realm where a new person comes on board and happens to disagree with something upon which twenty others agree.

People doing this are solving a problem that doesn’t exist: “how do we make sure everyone does this the same way when everyone’s currently doing it the same way?” It also tends to favor documenting current process rather than thinking critically about ideal process.

Let’s capture all of the stuff that we all do and write it down. Okay, so, coding standards. When working on a .NET project, first drive to the office. Then, have your keycard ready to get in the building. Next, enter the building…

Obviously this is silly, but hopefully the point hits home. The simple fact that you do something or that everyone in the group does something doesn’t mean that it’s worth capturing as trainable knowledge and enforcing on the group. And yet this is a direction I frequently see groups take as they get into a groove of “yes, and” when discussing standards. It can just turn into “let’s make a list of everything we do.”

Pointless Homogeneity

The concept of capturing the intersection of everyone’s approach and coding style dovetails into another problem with groups hashing out standards: a group-think bias. Slightly different from the notion that everything common should be documented, this is the notion that everything should be common. For instance, I once worked in a shop where developers were all mandated to use the same diff tool. I’m not kidding. If anyone bothered with a justification for this, I don’t recall what it was, other than some nod to pointless standards.

CookieCutter

You can take this pretty far. Imagine demands that you use the same syntax highlighting colors as your peers or that you keep your file system organized in the same way as everyone else. What does this have to do with the code you’re producing? Who knows…

It might seem like the kind of thing where you should just indulge the the harmless control freak driving it or the group that dreams it up as a unit, but this runs the risk of birthing a toxic culture. With everything, however inconsequential, homogenized, there is no room for creative thinkers to innovate with new approaches.

Make-Work Tasks

Another risk you run when coming up with standards is to create so-called standards that amount to codifying and mandating busy-work. I’ve made my evolving opinion of comments in code quite clear on a few occasions, and I consider them to be an excellent example. When you make “comment every method” a standard, you’re standardizing the procedure (mindlessly adding comments) and not the goal (clarity and communication).

There are plenty of other examples one might dream up. The silly mandate of “sort and organize usings” that I blogged about some time back comes to mind. This is another example of standardizing pointless make-work tasks that provide no substantive benefit. In all cases, the problem is that you’re not only asking developers to engage in brainless busy-work–you’re codifying it as an official mandate.

Getting Too Specific

Another source of issues that I’ve seen in the establishment of standards is a tendency to get too specific. “What sort of convention should we use when we declare a generic interface below an enumeration inside of a nested class?” Really? Does that come up often enough that it’s important for everyone to get on the same page about how to approach it?

I recognize the human desire for set closure; we don’t like it when a dresser is missing a drawer or when we haven’t collected the whole set, but sometimes you’ve just got to let it go. We’re not the IRS–it’s going to be alright if there are contingencies that we haven’t covered and oddball loopholes that we haven’t addressed.

Missing the Point

For me, this is the biggest one. Usually standards discussions are about superficial programming concerns rather than substantive ones, and that’s unfortunate. It is the aforementioned camel vs Pascal case wars or whether to put brackets and which kinds to use. To var or not to var? Should constants be all caps? If an interface is in a forest and doesn’t have an “I” in front of its name, is it still an interface?

I understand the benefit of consistency in naming, casing, and other syntactic considerations. I really do, in spite of my tendency to be dismissive and iconoclast on this front when discussing them. But, first off, let’s not pretend that there really is a right way with these things–there’s just the way that you’re used to doing them. And, more importantly, let’s not pretend that this is really all that important in the grand scheme of things.

We use consistent casing and naming so that a reader of the code can tell at a glance whether something is a field or a local variable or whether something is a method or a property or a constant. It’s really about promoting readability, which, in turn, is about maximizing maintainability. But you know what’s much harder on maintainability than Jones’s great constant casing blunder of 2010 where he forgot to use ALL CAPS? Writing bad code.

If you’re banging out behemoth methods with control statements eight deep, all of the camel case in the world isn’t going to make your code readable. A standard mandating that all such methods be prepended with “yuck” might help, but the real thing that you need is some standards about writing clean code. Keeping methods and classes small and focused, principles like DRY and SOLID, and other good design principles are much more important standards to which to aspire, but they’re often less concrete and harder to enforce. It’s much easier and more rote for a code reviewer to look for casing issues or missing comments than to analyze code for good software practice and object-oriented design. The latter is often less cut-and-dry and more a matter of degrees, so it’s frequently glossed over in favor of more tangible, simple things. Problem is, those tangible, simple things really aren’t all that important to the health of your applications and projects over the long haul.

It’s All Just Premature Optimization

The common thread here is that all of these standards anti-patterns result from solving non-existent problems. If you have some collection of half-baked standards at your company that go on for some pages and then say, “after that, follow the Microsoft standards,” imagine how they came about. I bet a few of the group’s original engineers or most senior people had a conversation that went something like, “We should probably have some standards.” “Yeah, I guess… but why now?” “I dunno… I think it’s, like, what you’re supposed to do.”

I suspect that if you did a survey, a lot more standards documents have started with conversations like that than with conversations about hours lost to maintenance and difficulty reading code. They are born out of cargo-cult practice rather than a necessity to solve some problem. Philosophically, they start as solutions in search of a problem rather than solutions to actual problems.

The situation is complicated by the fact that adoption of certain standards may have solved real problems in the past for developers on the team, and they’re simply doing the smart thing and carrying their knowledge forward. The trouble is that not all projects face the same problems. When discussing approaches, start with abstract and general abiding principles like SOLID and DRY and take it from there. If half of your team uses camel case and the other half Pascal and it’s causing communication and maintenance difficulties, flip a coin and set a standard. Repeat as necessary with other standards to keep the project moving and humming. But don’t make them up just for the sake of doing so. You wouldn’t start writing random code that may never solve any actual problem, so why create a standard that way?

  • Timothy Boyce

    The URL for the DRY wikipedia article got cut off.. I assume because it contained an apostrophe.

  • http://www.daedtech.com/blog Erik Dietrich

    Thanks. Didn’t occur to me to escape the URL. Fixed now.

  • http://twitter.com/kopelli Steve Evans

    Completely agree that some coding standards are overly prescriptive, especially when it has to do with odd combinations of whitespace. For example, we have one there every file needs to have the appropriate copyright header of `//{space}{tab}Copyright (year) (company name).{space}{space}All rights reserved.` I swear every file I have a tool clean up I end up wasting more time fixing that line than anything.

    The biggest thing is that there’s tools that make make this stuff non-issues. Between using ReSharper for naming consistency and configuring the auto-arranging of file members, and GhostDoc for quick documentation, I can breeze through a file to get it 97% of the way to fitting the company standards. But I definitely have to question the benefit of the large amount of time spent on the last 3%.

    And don’t even get me started on code reviews where the only focus is if the code meets the coding standard. That’s why tools like StyleCop exist!

  • http://genehughson.wordpress.com/ Gene Hughson

    “For me, this is the biggest one. Usually standards discussions are about superficial programming concerns rather than substantive ones, and that’s unfortunate.”

    Bingo…the few nuggets of substance get drowned out by all the extra crud. If Moses came down off the mountain with the 1,563,003 commandments, the response would have been “it’s easier to just go to Hell”.

  • http://www.facebook.com/jdpeckham James Peckham

    it’s “fixing” things you have control of in an out-of-control world. I’d just as soon let the IDE tell me a coding convention then have to even think about it.

  • Jordan Whiteley

    “If you’re banging out behemoth methods with control statements eight
    deep, all of the camel case in the world isn’t going to make your code
    readable”

    Sorta disagree. From someone that maintains a lot of crappy code, having consistancy in naming is sometimes the only thing that keeps me sane. Of course this is the difference between, finding and writing that 2000+ line vb6 monstrosity that goes 14 deep (not a joke, currently fixing it.) I think the problem you’re identifying is giving lazy code reviewers something to nit-pick about to look like they’re working.

    Readability is key and having inconsistancy in your naming standards is like reading a book where the author randomly changes the font and lettering size word to word. It presents an annoyance like a buzzing fly near your ear when you’re trying to concentrate. And worse with modern IDEs it’s totally unneccesary. In visual studio you’re a single ctrl-r-r away from fixing it and not doing so shows a horrible lack of care for your craftsmanship.

  • http://www.daedtech.com/blog Erik Dietrich

    The automation angle is a great point, and one that I should probably have touched on here. I actually use GhostDoc and CodeRush helps me conform to standards, and I’ve gone so far so to write plugins as well. If formatting standards are going to exist, I’d rather not bother thinking about them.

  • http://www.daedtech.com/blog Erik Dietrich

    That is a phenomenal quote in general, and spot on here. I chuckled aloud reading this.

  • http://www.daedtech.com/blog Erik Dietrich

    I often get that vibe from the drive for standards and general “low hanging fruit” items that I think of as shuffling deck chairs around on the Titanic. I’d imagine people who favor it for this reason are probably also resistant to the automation that you mention because it takes away the thing they control and gives the control to a tool.

  • http://www.daedtech.com/blog Erik Dietrich

    If you’re in a method like the one you’re describing (or, really, in general) consistent naming and casing is going to be easier to read than inconsistent naming and casing. I certainly agree with that. But my point is more along the lines that it’s much easier to figure out what’s going on in an inconsistently named/cased, 3 line method than a consistently named/cased 2000 line monster. In other words, if I had to pick one or the other: concise, well-factored code or consistently named and cased code, I’d pick the former every time.

    I also agree on the subject of automating formatting. If there is some kind of standard on the project, my habit is absolutely to automate conformance to it so that I’m not bothered with it manually.

  • http://twitter.com/HowardvRooijen Howard van Rooijen

    Interesting post – I wrote something similar a few years ago when I first came up with a prototype of what would become StyleCop for ReSharper (and why I thought creating such a tool was important): http://consultingblogs.emc.com/howardvanrooijen/archive/2008/05/29/microsoft-source-analysis-for-c-resharper-real-time-source-analysis.aspx
    These days I just see it as akin to a teacher demanding students to type up their essays – so you can concentrate on marking / feedback rather than having to decipher the scrawl :)

  • Sudhir Ravindramohan

    wow, quite an eye opener. thanks for putting this.

  • http://www.facebook.com/mel.grubb Mel Grubb

    The one compelling reason I have to enforce, or at least come to an agreement on coding standards can be summed up in one word: Merging. When two developers have different settings for things like bracket style or, worse yet, tabs vs. spaces, you end up with a useless version history for your files because every time they check in, they appear to have re-authored the entire file. I’ve tried to use Annotate or Blame tools to find out who I should talk to about a piece of code I don’t quite understand, and many times end up being told that I’m the one that wrote it. That’s not very helpful. Consistent formatting standards seem pedantic on the surface, but they vastly reduce the number of “merge fights” on teams where we’ve agreed early on to adopt them. Tools like ReSharper can take away the pain of this. As long as you reformat the document before committing, history becomes usable again.

  • Jordan Whiteley

    Oh yeah. I’d much rather work with 20 poorly named 3 line methods than a single well named 60 line method that does 20 things. Although from that perspective coming up with a good name for a method that does 20 things would be nearly impossible.

  • Timothy Boyce

    I tried to explain this to people on my team at a previous job. I convinced my manager to buy ReSharper and tried to get everyone to go along with using the code cleanup tool before they check in to improve the merging and history of code. Nobody would use it. I’m not sure if they were afraid of some tool messing with their precious code, or just lazy. My manager didn’t seem to get that everyone had to use it consistently, or it didn’t work.

  • http://www.daedtech.com/blog Erik Dietrich

    Well, I’d say that this definitely falls under the category of problems encountered and fixed by standards. I have no issue with creating standards when they solve a problem, and they certainly seem to here. I also definitely support using R# to automate them so that it isn’t something developers have to worry about while they’re thinking about the actual writing of the code.

  • http://www.daedtech.com/blog Erik Dietrich

    That’s an interesting project — I don’t use R# myself, but I imagine that’d be sort of satisfying to work on in an “I’m going to put an end to this bickering once and for all” sense.

  • http://www.daedtech.com/blog Erik Dietrich

    Thanks — glad you liked!

  • http://twitter.com/HowardvRooijen Howard van Rooijen

    Absolutely! That was pretty much the reason for it. Solve the problem and move onto issues that really matter.

  • Pingback: Exception Handling Basics | DaedTech

  • Pingback: Coding Standards | www.alanchavis.com

  • Thomas Winget

    Furthermore, I find that merging is never an issue anyway if you follow one simple principle: if you edit a file someone else made, follow whatever “standards” are present there. If the opening brackets are same-line, do that. If it’s tabs and you *really* hate tabs, use tabs anyway. I don’t even notice anymore, really…found out a month into a project I was helping on that I was using tabs and I didn’t even know. Vim is amazing here.

    The point is: unless whitespace and other concerns are legitimately getting in the way of productivity, follow the practices that were in place for a file/project. Don’t change someone’s braces, variable names, and whitespace just because you don’t like that person’s way of doing things…he’ll just change it back!