software = science + art + people
2012-09-27
[caption id=”attachment_580” align=”alignright” width=”285”] Yes, a restaurant really displayed this sign. I doubt it influenced anybody’s behavior…[/caption]
Some attempts to influence the behavior of other people succeed; others are doomed from the get-go.
Coding standards are usually written because we want to influence the structure or style of code produced by engineering teams. Sometimes they’re helpful; more often they’re ignored and forgotten; occasionally they provoke fireworks or bitter resentment.
I’m not sure there’s a guaranteed formula for success, but there’s a guaranteed formula for failure; let’s cover that first, and then see what helpful suggestions we can derive.
How to turn coding standards into epic fails
1. Micromanage.
Leave no room for personal style and creativity. Make no attempt to distinguish between meaty issues and utter trivialities. State all rules in absolutes; allow no exceptions. Announce enforcement in code reviews. Bonus points if you actually follow through on the threat, and double bonus points if you display some other developer’s code in front of the team as an example of egregious violations.
"Always put a space between an identifier and a curly brace, except in nested struct initializers where the first member is a string literal (other than NULL) or a #define'ed constant."
"Begin every function with a comment that specifies the name of the coder, the date the function was last modified, the purpose of the function, an annotated history of how the function has evolved over time, a list of functions called by your function, your zodiac sign, and the names of all parameters. Make sure that parameters are listed alphabetically (case-insensitive), with a blank line between each, and the explanatory text after the param name indented 8 - (len(param name) mod 4) spaces."
2. Overreach.
Make sure your coding standards cover every language, platform, compiler, and IDE. Don’t forget macros in Excel. For the sake of consistency, keep all rules invariant across all environments; if you like pep8 in python, you should definitely use it in VBA and java and C++ as well. Disallow javascript minify because it violates your naming conventions; make sure all environments use parens the way eLisp expects. Roll all of the standards out at once. Put multi-part version numbers on your standards, preferably derived from the year, month, day, hour, minute, second, and timezone. Check the standards into version control. Arrange to have the standards in the new hire orientation packet.
3. Mandate redundancy.
Choose rules that make code say the same thing in several different ways — preferably separating the redundancy as much as possible so it’s hard to modify correctly.
"End every function with a comment that says the function has ended. Make sure you include the function name in this comment. That way, we can find unterminated functions by looking for function identifiers with an odd number of hits when grepping through headers."
"At the top of every module, put a comment that gives the name of the module, a description of the module's purpose, then 'Copyright © Acme Corporation Inc., 20??, all rights reserved.' (Use the copyright symbol, not (c), and add correct digits for year...) At the top of every class, put a comment that gives the name of the class and a description of the class's purpose. Group all static methods together, and put //static methods
on a line above them."
4. Beat a dead horse.
Tell, don’t show; every rule should be described in careful detail. Put your standards in a Word doc; make sure it has a title page, table of contents, index, and a header and footer that contain an embedded version stamp, author name, and last print date. Use bold, italics, and all caps liberally (through styles, not one-off formats; remember that you’ll be releasing updates…). Export the doc to help those who can’t read your format. Attach four versions (doc, docx, pdf, eps) to a wiki page, and to a department-wide email. Print a master copy on the color laser printer, then go to Kinkos and have a color copy printed and bound for each employee. Arrange to have it delivered to their desks.
Make a powerpoint slide or two highlighting key areas in the table of contents; attach that to the wiki as well. Ask for time in a company meeting to show your slides, so people are mentally prepared for the doc that’s been delivered to their desks. Apologize for making some decisions by fiat instead of consensus; give a few specific examples.
A few days later, broadcast a follow-up email asking for feedback and reminding everyone of new enforcement procedures. After you realize that you didn’t repeat your original attachments in the follow-up email, reply to all with the missing attachments. After that, reply to all with a hyperlink to the wiki page that has all the attachments, since that page will be guaranteed to be kept up to date as the standard evolves.
Suggestions for success
If the foregoing ideas don’t excite your enthusiasm, I endorse the following:
If you read that list and think: “Well, then, why have coding standards at all?”, then I have done you a disservice. Teams definitely can benefit from conventions and standards, in many cases. Here are a few rules I might propose in the next coding standards I work on.
Sample suggestions (not “rules”) from a wise coding standard
In general, model new code after the conventions embodied by recent and cl code you see in the codebase. The following modules are known to be good examples: moduleA, moduleB, … (Value: high. Cost: low. Pointing out some good examples will do more than a dozen pages of text. Also, pointing people to new code allows wisdom about conventions to accrete organically.)
Keep files small. (Value: high for casual maintainers. Cost: usually low. Many good habits are tied to this guideline, including loose coupling, encapsulation, refactoring, and modularity.)
Clean up messes. Delete unused files, functions, and blocks. (Value: high. Cost: low. Casual maintainers don’t have to wonder about the significance of something inert. Reinforces refactoring.)
Use descriptive names for classes, functions, variables, and es, so you don’t have to document what should be obvious semantics. (Value: high. Cost: low. Eliminates redundancy and encourages good refactoring habits. Good code is named right.)
Comment what can’t be made obvious. >(Example where comment might be helpful: subtle precondition or postcondition on a function. Value: high. Cost: low.)</em>
Carefully follow the codebase’s error and exception strategy. (Example: “In C++, use RAII to guarantee exception safety. Make sure all errors are complete sentences, since they’ll appear in logs and be read by end users.” Value: high. Cost: medium.)
Name files and directories with a consistent pattern. (Example 1: use all lower-case, with underscores between words. Example 2: use Java’s conventions. Value: high. Cost: low. Eliminates #include “WrongCase.h” problems on *nix; makes batch processing easier.)
Roughly, follow formatting conventions common to your language and recommended by your IDE. Use the team’s standard indent (e.g., 4 spaces) so different editors don’t produce ragged gobbledygook. (Value: medium. Cost: low. Mainstream formatting is usually pretty readable. This rule is stated with enough flexibility to leave moderate room for personal preference.)
Name unit tests after their main assertion, so you know what’s wrong when you see what failed. (Example: test_removeChild_throws_when_container_empty. Value: medium. Cost: low.)
Benefits
Stupid coding standards are offensive and a complete waste of everybody’s time. If you promulgate standards like the ones I offered at the top of this post, you deserve to fail. On the other hand, rational, reasonable standards can help a team enjoy working together, flatten the learning curve for new folks, promote good habits, cheapen automated analysis, and foster pride of ownership.
Action Item
If you have existing coding standards, look at a few guidelines and decide A) how much technical and business value they provide; B) how easy they are to learn and follow; C) how well they're implemented. Do you see any places where you want to adjust?
If you want to create a coding standard, make a list of rules that have a high ratio of value to cost. Pick the top 10 (or as many as you can fit on one (1) sheet of paper with a normal font and margins). Float a few past other thought leaders. Keep the best ones only.
Comments-
-
Wheeljack, 2018-06-18:
I caught this way too late to matter but I would say that the "standard" (because we all know it's not one) should be available not just for new hires but interviewers as well. Concealing an insane set of half-baked rules really just wastes competent programmers' time and reinforces the notion that you did this deliberately to trap them. Let me just walk out of the interview or turn down the offer before we get to the point and save us all alot of trouble. Because the instant some framework monkey struggling with Hello World gets on my case about bracket placement, that's it, I'm done. I'll hang around and collect a paycheck until I find something else but you won't get anything of value out of me for whatever time remains.
Daniel Hardman, 2018-06-18:
Agreed!