Developing Programmers .com

Local Search:



This site is optimized for standards so you can use any standards compliant browser:

Valid XHTML 1.0 Transitional
Valid CSS!
(RSS) RSS Feed

Web Search:
Google


Wednesday, 2 November, 2005

Group Style  

Every programmer will develop their own preferred style over time. Often the style changes and evolves as you learn.

Working in a group, people’s preferred styles come into conflict. Then it helps to be conscious of the purpose of styles so you can stick to what’s important rather than personal preference.

Armed with a clearer picture of what’s important in a style, we move on to style negotiation and some different ways the style conflicts can be resolved for a given project.

What is Style?

Basically style makes your program predictable by communicating what’s going on. Sometimes it’s fun to be unpredictable but when programming in a group predictability is always a good thing. Being predictable means that people can infer things about your software without having to read it all. Good style communicates well so that developers know what to expect and can make assumptions safely.

Style in programming is an umbrella term that covers several things, such as:

  • Code formatting — really just whitespace layout.
  • Naming conventions — including file and directory names, namespace and class naming, parameter and member naming, and even sometimes local variable naming.
  • Documentation — Design diagrams, UML, written notes, API documentation (usually generated from comments), inline comments, etc.
  • Code layout and organization — Deciding which abstractions really help, how to break down the task into functions, choosing what to represent as a class, etc.
  • What you consider to be readable actual code (or whether you consider making code readable!)

Basically style is all about readability, which makes good style the opposite of code obfuscation.

In obfuscating code, the programmer makes it deliberately difficult to see what the code is doing. There are code obfuscation contests where the winner writes the hardest to understand code. Typical tactics include:

  • Removing semantic information from the names of program symbols (eg. "int zz()" to replace "int get_random_number()").
  • Either removing indentation or arranging it to be deliberately misleading.
  • Making the logic of the program disorderly, for example by performing bits of different operations in a randomized order rather than an obvious sequential pattern.

In short, code obfuscaters make the program much harder to understand than it was to write.

The opposite of this (what we’re calling “style”) therefore involves::

  • Making it deliberately easy to see what the code is doing.
  • Using variable and function names any any other opportunity to add semantic information about what’s going on. This includes renaming variables or functions if their purpose changes.
  • Using indentation to make block structure clear
  • Arranging the flow and logic of the program to be step-by-step and as obvious as possible

In short, a programmer with good style writes code that looks simpler and easier to write than it really was. They write their code defensively so it will tell you if you used it incorrectly, and so that its correct use is apparent at a glance. Truly experienced people in any field have a tendency to make things look easier than they really were. That’s a good thing to aim for; even the weakest programmer in your group should be able to understand your code, even if they couldn’t have written it.

Features of Good Style

I’ve already named several features of good style, but there’s more to know about each one:

Code formatting seems to be what most people first think of when “coding style” is mentioned. Really this is just where the whitespace is in your source files. Do you use blank lines to communicate new tasks or sections of a program? Do you prefer the open brace at the end of an "if()" or on the next line? Everyone has a preferred layout but you should be able to read a variety. The important thing is that it communicates syntactic blocks well (eg. indenting the body of for loops), and that it communicates semantic blocks well (eg. putting a blank line between groups of related statements and typically several between functions). Just as paragraph breaks are important in English writing, whitespace can convey similar meaning in program code.

Naming conventions are more important than many people realize. An inconsistent naming convention leaves people having to search the source code for each function they want to call to find out what it was called. Ideally it should be possible to guess most function names because they follow a predictable pattern and convey a meaning. Good class names are usually a noun or noun phrase, and function names are usually verbs or verb phrases. Have a consistent way to represent multi-word symbol names, such as underscores between words or starting each word with an uppercase letter.

The main thing is to be consistent and not to avoid using multiple words when it’s appropriate. Even the standard C libraries include some inappropriate single-word function names: can you guess just from the name what the difference between time(), clock() and ctime() are? Imagine if they were renamed to seconds_since_epoch(), clockticks_runtime() and time_in_seconds_to_string(). These might not be ideal names but they do communicate more than a set of apparent synonyms. Don’t go overboard though; everyone knows that i is a loop iterator variable. Convention serves adequately here.

When considering naming conventions don’t overlook filenames: when a project grows to hundreds of files it’s handy to be able to guess which filename you want.

Documentation is an essential part of professional programming. It is important to make it easy for a new team member to learn an overview of how the program works and specifics at a glance for anything they might need to edit or call. The high level documentation is a real document that is separate to your code (but usually stored in a similar place). The API documentation can be generated from inline comments in the code if you plan ahead and the algorithm level documentation is plain old comments that you’re hopefully using already.

Code layout and organization is the “design decisions” which are often not considered to be style at all. Spending the time to make the right abstractions and realizing tricks like “hey saving in XML is the same thing as saving RTF format but using a different template” can save you a lot of time, so long as you’re alert to which tricks actually help and which are a diversion from just getting the job done. A mistake I’ve seen made often is writing 10 (or in one case 260) of the same function with only slight changes from one to the next. Bug fixes rarely made it to all of the similar functions.

The code itself can be organized in a variety of ways. Decisions like where to declare variables are not important as long as variables are declared. I heard a satellite got lost once because of a misspelled variable name in a language that didn’t require declaring variables… The main thing here is to keep things simple.

Individual and Group Styles

Every programmer develops a style that they prefer. It makes the most sense to them. In a group, two programmers will rarely agree on all the specifics of a style. This means you can get a mix of styles, depending on how strict your group decides to be. Even with fairly strict style guidelines there is enough individuality in there that you can usually pick who wrote certain sections of code.

Corporate environments will often define their own style guide and inflict that on all their developers. It’s better than no style, and it can be better than a mix of styles. Just beware of being over-strict if you are defining such a style guide; the way that you write won’t be everyone else’s way and there is room for a little variation without causing havoc. Try to stick to API level style issues like function naming conventions and just enforce common sense beyond that.

In my office the rule of thumb is “she who creates the file, sets the style”. This allows the areas we are working on most to be in our own style, and gets us to respect each others decisions when working on someone else’s files. We still need to be a little careful of global symbol naming with this rule. And the occasional editor war as tabs are used differently by different people, resulting in apparently random indentation when you load someone else’s code in your editor.

Aside from friendly jabs about editors and personal preference, there are two behaviors that cause problems with style in a group: ignoring it altogether and writing messy code, or getting too particular about it and (for example) trying to force everyone to put a space after the second comma in a parameter list but not after the first…

The first is going too far in the “lazy” direction and is bad for a group because once the code gets messy it takes time to fix, so it can sometimes seem easier to keep it messy. Style takes little or no extra time if you do it as you go.

In the case of the over-particular coder, they have probably been reading only their own code for too long and need to broaden their horizons. If you have trouble understanding someone with a British or an American accent and as a result insist they are not speaking English and need to change, then you’re just not really trying to communicate. Any good programmer can read a range of styles, so long as there is a style.

Keeping Everyone Happy

Clearly there’s a balance to be struck between consistency and flexibility. The best way to do this will depend on the people involved and the requirements of the code.

A friend of mine used to work for a company where they had a style that was enforced by a program that automatically reformatted the code into the company’s style. This meant the style was very consistent and at first seems a little draconian.. except that the same formatting program could be configured to just about anyone’s preferences. This meant that when checking out code, each developer would have the code arranged the way the like to see it. When checking in code, it would be formatted back to company standards just before checkin. Apparently this worked very well for them.

A more ad-hoc approach works well where I work. Each project has a lead developer who decides on naming conventions and overall API organization for the software. We use Doxygen to create API documentation and that is an expected part of the style. However the specifics within files are left up to the creator of the file. Within functions, where symbols are local not global, whoever wrote the function decides what naming system they would like to use. This approach keeps the large scale code base regular enough to be predictable, while letting programmers do their own thing for the details. It does require a little respect to see “my workmate has opted for opening brackets at the end of a line instead of on the next line so in their function I’ll keep doing the same”.

Posted by sarah at 2:46 pm in: Style , Teamwork (1217 views)

0 Comments

Please use the DP Forums for further discussion of this topic.