Sunday, July 14, 2013

Coding conventions

People spend time in corporations writing coding convention documents. Often they think in terms of an ideal world. Enforcing coding conventions creates friction on teams. Coding conventions should be light weight. Coding conventions should make the code easier to read, understand, maintain, and debug. Coding conventions should not add unnecessary overhead to the project.

Sun Microsystems published the above Java coding convention in 1999. Most of the convention is irrelevant since formatting is handled by Eclipse.

I don't completely agree with their code structuring conventions. The first thing that their coding convention assumes is that programmers adequately comment their code. Since we know that this is not the case you should at least write code which is SELF DOCUMENTING. See below.

1. Embedding function calls inside of function calls may be faster to code but makes the code more difficult to debug, read, and understand. The code is also self documenting if the var names are descriptive. Since people put limited comments in their code using descriptive var names is the minimum requirement.

var = someMethod1(longExpression1,
                someMethod2(longExpression2,
                        longExpression3));

Should be

descriptive_var = someMethod2(longExpression2, longExpression3);

var = someMethod1(longExpression1, descriptive_var );

Now when you step through the debugger you can see the return value for the first method.
Others who read the code can see what the descriptive_var represents.
  
2. Complex boolean equations should be broken down into individual booelnas. The code is easier to debug, read, and understand. The code is also self documenting if the boolean names are descriptive. Since people put limited comments in their code using descriptive boolean names is the minimum requirement.

//DON'T USE THIS INDENTATION
if ((condition1 && condition2)
    || (condition3 && condition4)
    ||!(condition5 && condition6)) { //BAD WRAPS
    doSomethingAboutIt();            //MAKE THIS LINE EASY TO MISS
}

Should be

// each var is descriptive and describes the condition
// each var is in effect a COMMENT
// the debugger shows the value of each boolean in the complex conditional expression

dv1 = condition1 && condition;
dv2 = condition3 && condition4;
dv3 = !(condition5 && condition;
dv4 = dv1 || dv2 || dv3;

if (dv4) {
    doSomethingAboutIt();     
}

3.This is nonsense. The best programmers I know declare vars when they are first used in blocks not at the beginning of blocks. It makes the program easier to follow. You don't have to jump around to see the type of the var. The program looks like a dataflow/pipeline (data announces its arrival) and is easier to DEBUG.


6.3 Placement
Put declarations only at the beginning of blocks. (A block is any code surrounded by curly braces "{" and "}".) Don't wait to declare variables until their first use; it can confuse the unwary programmer and hamper code portability within the scope.

void myMethod() {
    int int1 = 0;         // beginning of method block

    if (condition) {
        int int2 = 0;     // beginning of "if" block
        ...
    }
}

4. Put vars in returns. Make the code self documenting and readable.

return (size ? size : defaultSize);

Should be

int realSizeOfSomeObject = (size ? size : defaultSize);
return realSizeOfSomeObject; 

5. There are some guys from MIT who completely disagree with putting the else on the same line as the left curly }. They think the else goes on the line below the curly. I agree with the MIT guys.

7.4 if, if-else, if else-if else Statements
The if-else class of statements should have the following form:
if (condition) {
    statements;
}

if (condition) {
    statements;
} else {
    statements;
}

if (condition) {
    statements;
} else if (condition) {
    statements;
} else {
    statements;
}

6. No assignments in condition checks...
Do not use the assignment operator in a place where it can be easily confused with the equality operator. Example:

if (c++ = d++) {        // AVOID! (Java disallows)
    ...
}
should be written as
if ((c++ = d++) != 0) {
    ...

}