The Diminishing Return on Code Uniformity
Filed Under Code, Quality Controls, Software ProcessLast week Steve Rowe had a nice discussion on the question – Is There Value In Code Uniformity? Although I left a comment, I thought I would expand upon my thoughts a little more.
I do agree that every team must have (and enforce) some basic standards of code uniformity. These may include items such as:
- Use PascalCase over camelCasing or Hungarian notation
- Prefer language keywords over hard types (as in – int not Int32)
- No single line if statements or use of ternary operators such as ?
- All references to class member variables will be prefixed with this.
These types of standards give a clear outline of the fundamentals of code cleanliness and uniformity that can aid in a team environment.
However, often I see team leads attempting to micro-manage these coding standards. The majority of these standards have very low impact on overall readability and maintainability. I have see religious wars break out over stupid standards such as:
- { on new line or same line
- _ or m_ in front of private variables
- The order of class member declarations (private vars, ctors, props, methods [in alphabetical order], etc…)
It is unfortunate that I see teams creating standards not only littered with these types of rules, but fore-running as the core foundation. These types of standards do have worth, but must be enforced with a much lighter touch as policing these types of infractions just does not yield overall benefit to the application.
In the large scheme of things these types of code uniformity infractions are small potatoes. It is the equivalent of creating a standard way of monotone communication for optimal office efficiency – yeah ok.
I am not advocating that we should not have coding standards nor that they should not be enforced by frequent code inspections; however, I am of the belief that developers write code with minor deviations that show the same uniqueness you would see in articulated words or drawn pictures. Instead of attempting to find a happy standard, let’s celebrate our minor differences in writing code and be more adaptive to different flavors.
Sometimes the small things do matter – but not in this case.
16 Responses to “The Diminishing Return on Code Uniformity”
You’re right that the impacts on readability are negligible, but the impact on scanability (solubility) can be extreme.
Readability is only one side of the coin. I read when I’m working in detail on the code site that I’m interested in. I scan to find where I need to be and what ancillary things I might need form a map of to support my detailed work.
If you’re making me read stuff that I should only need to scan, you’re stealing productivity from me and forcing me into levels of detail that aren’t necessary for my work.
My rule of thumb for the team is:
It’s 11 pm, Asia is on the phone screaming at you and you have to fix someone else’s code. What do you need to read?
This allows for some variation, while excluding stupid stuff like 10 nested if statements and variable names like v1, v2, v3 … that may have slipped by code inspection.
I agree as well.
IMHO, the 2 main focuses here are readability and expressing yourself in a coheretent but concise manner. Although these do not always go together, a balance between these extremes is essential.
On a side note, I love the ternary operators as they are much more “scannable” and express the situation quite clearly. I don’t understand the reason so many people hate them. Of course if you nest them in each other, I will feel compelled to publically ridicule you, lol.
Moderation, in all things…
I have seen teams who had very rigid policies turn out some horrific code b/c of all the structure (usually b/c they end up commenting every line, commenting their comments, telling their life story, the state of the union, etc.). Rigid structure also takes time to implement and can actually inhibit the thought process.
Of course, this makes addins, such as resharper, VSTS, etc., very valuable since it can enforce a bit of structure after the fact but does not interfere w/ the coding process all that much.
I think code uniformity is taken way too seriously at the place I work now. We routinely get JIRA issues reopened for whitespacing, indentation, SQL keyword capitalization, missing semi-colons at the end of SQL statements, and various other minutia.
The mantra is that it is well worth taking the productivity hit in order to have quality code, but I think that this lower order analysis (when to the feedback provided by FxCop, NDepend, or Vil) is simply a distraction.
I have to admit that it is hard to feel good about spending all this time conforming to what I feel are essentially trivial idiosyncracies. I often wonder at what point it stops being about quality and readability and starts becoming about soothing OCD tendencies of certain individuals?
One important aspect of any set of code standards is to show the importance of each item. One simple way to do this is to mark each as being either a Rule or a Guideline. I’ve also seen schemes where the items are rated on a scale.
I also like to divide them into things that require human judgement (e.g., “variable names are meaningful”) versus things that can be enforced, or at least spotted, by programs (e.g., “no tabs”). Humans needn’t bother memorizing the latter, if you’ve got decent tools hooked into your process.
@Scott
I do agree with you, but I guess the core of my theme really is – who should give more, the creator or the maintainer?
This is an interesting question because most projects live and die based on some initial timeline – so shouldn’t we allow developers to code comfortably?
On the other hand, it is said that 80% of software costs are in maintaining it – so shouldn’t we code for maintainability?
A nice little catch 22. However, with current IDEs and enhancements such as Reshaper we can find and refactor code at lighting speeds, and this is why I find these more obscure FxCop like standards low on my team’s priority list.
@Russell
Pass this message to your boss – the enforcement of your coding standards is lame and has no realistic ROI – Codesqueeze has spoken =P
I would think that, at the very least, naming/style should be consistent among items in the same container. For example, code in the same code (.cs, .java, etc) should be uniform. File names in a folder should be uniform, folder names in a project should be uniform, project names in a solution, etc, etc, etc.
If I go from one .cs file to another and they’re formatted differently, but uniformly, I’m less inclined to complain than if they’re all over the place within individual files.
I can adapt to K&R braces or PASCAL braces, I do not want to have waste brain cycles working with both within the same code unit. It’s inefficient.
Nathan,
> I love the ternary operators as they are
> much more “scannable” and express the situation
> quite clearly
Ternary operator statements are less scannable. I look for indents to look for branches and conditional flow control and value assignment. Ternary operators don’t offer the same visual hints to scanning.
Scanning is specifically not reading. Scanning and scannability is more significantly impacted by the geometry of the code and the consistency of the shapes and patterns used to communicate certain kinds of programming concerns.
The significance of a ternary operator to someone who is scanning is that there’s a conditional branch there, and it may very likely be missed because it isn’t shaped like the kind of conditional branch that can be perceived at scanning speed.
Scannability is drive-by readability. If you’ve found a ternary operator statement while scanning, it’s either because you got lucky, or you stopped scanning and switched to reading without taking notices of the change in modes.
Max,
> who should give more, the creator or the
> maintainer?
The maintainer. Maintenance is 80% of software cost BY PHASED DEVELOPMENT. If you have a maintenance phase, and based on common understanding of the distinct place in phased development lifecycle where transition to maintenance happens, the the 80% mark is true.
The reality is that the moment of software creation is so infinitesimally small that it’s barely worth mentioning.
There are two phases of software development in contemporary processes:
1-) thinking about about you’re about to do, and
2-) everything that comes after you’ve thought about it and wrote it down in code.
Once any single byte of code exists, it’s in maintenance – even if it was created only a minute in the past. Software Creationalism says otherwise, and gives rise to the 80% number, but it’s a software cosmology based in an software lifecycle ideology that has proven to be pretty seriously flawed.
> so shouldn’t we allow developers to code
> comfortably?
Absolutely, but that means that they should comfortably work within set constraints. The kind of disciplined software production that leads to levels of agility that come after merely solving the software defect problem with unit testing and TDD depend on this extent of constraint and control – just as does the Toyota Production System that we all hold up as a paragon of agile virtue.
The software developer plays the role of both ideator and production worker. He has to come to terms with the different constraints that apply to software ideation versus software production, and accept that production work isn’t as willy-nilly as ideation tasks.
It’s the attraction to the stream-of-consciousness ideation that permits the entitlement to phased development. It gives some folks on the team the license to do all their work in those contexts that labor under fewer constraints. It’s a selfish and destructive pre-disposition for software developers, and I’m certainly not immune to its temptations and have given in to them on many an occasion.
Ethics, responsibility, and moral imperative suggest that I remain vigilant, however, and part of that vigilance is informed by a practice of the constraints that I’m accountable to.
Thanks for the insight. I’m glad to see what you think should be in and out of coding standards. They sound very reasonable. My opinions align very well with yours on this issue.
One minor question, why do you say that this.variable should be in the standard but that we shouldn’t argue about m_ or _. Aren’t those the same issue? They are both trying to solve the same problem.
@Steve
Pretty much. One man’s battle is another man’s war. ..
Once when I worked at MSFT, I had an architect slap my hand and overnight he refactored all my code to include this. on all variables.
Guess that experience left me with suppressed memories and unconscious mental imprinting that it needs to be done. Something I am picky about, but could easily be placed in the “Don’t care” pile if I was to get over my own neurotic behaviors.
Funny how the most obvious lesson in life, all things in moderation, needs to be repeated to people over.. and over… and over again. Problem is some people are freaks that have no sense of balance or moderation and they’ll shank you in the bathroom if you dare dangle a curly brace in their face.
Code uniformity is about *respect* for your fellow developers, you want everyone to be able to use and maintain the code and you want that in return so everyone agrees on what is important and what’s not. Sure you may hate an indent of 4 but at least you got them to use spaces over tabs. Uniformity to a certain level is *highly* important, you just have to figure out where that point of diminishing return is.
Now if you have that one crazy code-mumbling egotist coder then just smile and nod and forget to invite him to the next standup where you talk coding styles. Sorry crazy guy, you’ve got to give in to the good of the team, not your own ego, so just be happy with your stapler and be quite 🙂
I’ll be banging my head against developer psychology for years over this issue, but there’s a level of agility that can’t be had without solubility, and when solubility is itself uniform in a codebase, it’s emergent properties ratchet up productivity to yet another level beyond what I’m seeing in preceding practice combinations.
Explaining TDD to a naysayer has always been like showing an atom to someone who has a scope that stops at the molecule. Same for solubility, except now the audience is veteran TDD’ers – and that’s really frustrating as there’s an inherent hypocrisy in asking folks to suspend conventional disbelief and just try something new while not continuing to do the same.
Everything new becomes old, and at some point, folks are just going to hold on to a given era and remain there. This is presently the frustration I have with my circle of veteran agilists. Some prop pilots will simply never want to fly a jet – especially if it means a significant investment in yet more learning and re-learning.
I stand by my position on code uniformity – when we’re talking about solubility as a next step after TDD and when practiced in that context.
Sorry, I don’t see much difference (aside from semantics) between using “this.” or an underscore or m_ in reference to member variables.
All three are designed to differentiate member variables from arguments, constants and properties. Pick one and use it across your project.
I think people spend too much time worrying about formatting issues (say, in code reviews) instead of focusing on the fact the code is wrong/buggy.
Max, that architect thing is funny. When I was out at MSFT last year we were told explicitly NOT to use this. at all. Apparently there was some big flame war about it and it was decided not to use it.
[…] The Diminishing Return on Code Uniformity. by Max Pool ({codesqueeze}). […]