Monday, December 5, 2011

Join Fresh Start Week 2012

Soon we'll be on the other side of Christmas and starting a new year.

How about for the first week of January we try doing without copy-and-edit programming. What would happen if we were to write code off the top of our heads?

Don't just hand-type the example code you would have copied anyway, but try writing it as if the code you really wanted already existed.  How would you have liked to initialize that class? When you are writing a test, do the order of the parameters of that method make sense? Are you doing three- or four- or five-step operations that ought to be their own function? Is the method you need a member of the object where you would expect to find it? You can't find out by doing copy-and-edit programming.

Let's all try the grand experiment of not copying ANYTHING for the first work week of January. What could it teach us? What could it hurt?

The hashtag will be #freshstartweek.

See you there.

Friday, December 2, 2011

Single-Return, AKA: Elephant-proofing your bathtub

Single-entry, single-exit programming was a great breakthrough that led to a serious improvement in the lives of many programmers. In the jurassic period of software development, anyway. In the modern era, among good programmers, I think that single-exit is an example of the many once-best practices that outlive their usefulness.

Method length and nesting are our primary enemies. Multiple returns in nested, long methods turn trouble into disaster for the poor developer who has to understand and debug a routine, not to mention the guy who lost the coin toss and has to actually modify it.  Once code is bad, multiple returns makes it far worse.

Start with pure function length:
  • In a 500-line function two returns is dangerous, and five would be maddening.
  • Drop to 50 lines, and it's still pretty daunting.
  • Drop to 10 lines, and the risk of missing a return or misunderstanding the method is slight.
  • At 5 lines, there's no hint of the problem that single-exit solves.
Switch to nesting depth:
  •  If you are nested 15 conditionals and loops deep, that extra return is obscure with a capital O. 
  • At 5 conditionals deep it's frightful. It's hard to tell at a glance which lines are being executed and when.
  • But what if you're never more than two levels deep in a function? Returns are crazy obvious.
See how this one rule serves you supremely well when your code stinks, but does you no favors when your code is short and clear? 
Q: "Doctor, I broke my arm in two places! What should I do?"
A: "Stay out of those places!"
Single-entry/single-exit can even be harmful to the readability of an otherwise short function if it forces variables to be created up front instead of at first use, or if it causes code to be more deeply nested. 

     int doSomething(int parameter) {
        int result = 0;
        if ( 0 != parameter ) {
           result = x/parameter;
       return result

Here the real feature of the function (the division) is hidden inside an if clause. It makes the code seem as if its goal is to return zero, and that the division is a side effect that occurs when a condition is just right. It'a s funny de-emphasis of the essential goal of the function.

Let's invert the condition to create a guard clause instead:

   int doSomething(int parameter) {
       if ( 0 == parameter ) {
           return 0;
       return x/parameter;

The actual functionality is exalted, and the early return is more clearly an effect of having a parameter that you must protect against. The readability here is not degraded, but instead enhanced.  This is a good time to remind the reader that the shortness of the function makes it so.

It is no worse even if I squish an if onto one line (another no-no in many shops). 
     int doSomething(parameter) {
       if ( 0 == parameter ) {return 0;}
       return x/parameter;

The same rule seems to apply when there are more parameters to check and when the work to be done is more than a single line:

     int doSomething(int parameter1, double parameter2) {
       if ( 0 == parameter1 ) {
           return 0;
       if ( (parameter2 < 0) || (parameter2 > 1)) {
           return 0;
       double part1 = parameter2 * x;
       int result = int(part1/parameter);
       return result;

We have the advantage that the function is divided into checking parameters and returning results, so it is still pretty readable and clean. There is little nesting, and few lines. On the other hand, the astute reader will notice that we're up to 11 lines now, and with a little more expansion we could have a Long Method on our hands, at which time the single-exit rule will apply again (welcome back to the Jurassic period).

We will outgrow an awful lot of our hard-n-fast rules by writing small, clear functions. A lot of "best practices" are really just "ways to tolerate poor practices."  

Some of our old 1970s C programming rules were very valid in their time, but following them when they don't apply is as silly as a Chicagoan elephant-proofing his bathtub.  

Thursday, December 1, 2011

Performance Appraisal Time?

As you head into year-end appraisals, here are a few resources for you.
Note: most of you employees do want time with their bosses, they just don't want a once-a-year backward-looking judgement. They'd rather the boss was a part of their team and gave forward-looking direction all of the time. More feedback is better than less, and more engagement too. 

For some other pointers, see: