TODO or not TODO

Are TODOs in source code good or evil?

In my view, TODOs are a tool and like any tool, it can be misused. I do agree with most of the critism but if they are used with care and if they are actively managed they can improve productivity.

Sure, TODOs tend to accumulate and, yes, there are selfish developers who use them to acquit themselves from checking in sloppy code (which they will never clean-up). Yet, there are situations where they are appropriate.

Sometimes it just makes sense to check-in code that is not 100% done. For instance, if all of your requirements are not settled yet or you are uncertain about some boundary cases. Here is my litmus test: if your unfinished code already provides value to somebody else and it doesn’t break existing tests it is OK to check it in. Be it a tester who needs a running system to develop test cases against or a coder who needs your class to continue her work. Maybe it’s a sales person who needs a quick tentative solution for his trade show. Unfinished code is especially appreciated in the ‘bazaar’ software development model.

If you accept the notion that unfinished code is useful if it already provides value, you probably also agree that it is not a good idea to keep the list of open issues in your head; even scrap paper is only slightly better. To me, it is much better to record ‘tentativeness’ very close to the code.

However, it is essential to manage those TODOs — if you don’t manage them, they will eat you alive.

In order to manage you need to track and tracking is much easier if your TODOs follow a standardized format. Once you have a standardized format you can easily extract metrics. If everybody used their own style of TODOs it would be very hard to control them. A mix of TODO, FIXME, BUGBUG, ???, ### is TODO hell.

After years of experimenting, I’ve found this style of TODO comments to be the best:

    // TODO:2008-12-06:johnc:Add support for negative offsets.
    // While it is unlikely that we get a negative offset, it can
    // occur if the garbage collector runs out of space.

Let me briefly describe why I consider this format to be superior.

First of all, it starts with ‘TODO’ in all capital letters, which is good, as it is recognized by many editors/IDEs and highlighted in a special manner. This makes it easy to recognize TODOs for human beings when browsing source code.

Next comes the date in ISO 8601 ‘extended’ format. Not only does this tell you when the TODO was added: it allows you to easily sort your TODOs:

    grep -R TODO: * | sort

The sorted output will show you which TODOs have been around for a long time, maybe for too long a time.

After the ISO date comes the name of the TODO owner. I suggest you use login names, but it doesn’t really matter as long as it is unique and can be easily mapped to a real person’s name. Due to the fact that the name is surrounded by colons you can build a list showing who owns the most TODOs:

    grep -oRE "TODO:[^:]+:([^:]+)" * | sed -e "s/^.*://" | sort | uniq -c

Finally, there is a brief summary that describes the reason for the TODO; if necessary, additional text follows on the next lines. Describing a TODO is essential: it tells developers why it is there; leaving it out is akin to putting up a ‘Watch out’ warning sign without giving any additional clues.

In order to extract information automatically, the standardized format must be enforced. This grep command will catch most ill-formed TODOs:

    grep -iRE "todo|fixme|bugbug|???" * | grep -vP "TODO:d{4}-d{2}-d{2}:.{3,}:.{10,}"

In addition to pinpointing typical TODO comment keywords it ensures that the date is well-formed and that the owner and description fields are not omitted.

Ideally, you run such scripts automatically every time a developer checks-in changes. If you don’t have testbots you should at least run them as part of your daily build procedure. In case you don’t even have daily builds (pity you!) it is the job of the project lead to execute them regularly.

TODOs are useful for modern, release-early-and-often software development processes; by standardizing their format, all of the common disadvantages can be overcome. I suggest you put them near the top of your TODO list.

Tools I Carry

I recently wrote about the most important tools of a software developer. The tools that I mentioned are important to be a successful developer — they are not sufficient to master the other challenges of life.

Being the geek that I am, I carry all sorts of things in my pockets — things I couldn’t live without. Today, I’ll do a headstand and show you what I’ve got.

First of all, there is my swiss army knife. I need it for all kinds of situations: tightening screws, cutting of loose threads on clothing, opening bottles. Last spring we went on a hiking trip and my son got bitten by a tick — I used my knife’s tweezers to pull it out. It’s amazing: once you carry a swiss army knife, all kinds of occasions arise to use it and you wonder how you could have survived so far without it.

But I had to make a trade-off: naturally, I wish to have as many functions on my knife as possible: many screwdrivers of different shapes and sizes, a magnifier, scissors; and it should have a big blade such that its possible to cut off a slice of bread from a big loaf. All of this is available from Victorinox and Wenger (they even have knives that come with LED lights and USB memory). Alas, there is only limited space in my pockets! I certainly don’t want to carry a brick around. After years of experimenting with various models, for me, the Wenger “Evolution 10″ is the best compromise. Always remember: the best knife is the one that you have on you; a 30+ function knife is of no use if it’s left in your cupboard.

I also need to have a pen on me. Not just an ordinary five cent plastic giveaway pen that might leak ink or run dry. Typically, those pens are also too big to carry them in your pants pockets (I rarely wear shirts, so all my tools need to be placed in my pants pockets). I prefer the famous Fisher ‘Bullet’ Space Pen. This pen is just so cool, so small, so sleek, so robust, so timeless. It comes with a special pressurized ink cartridge that allows you to even write up-side-down — on wet paper, if necessary.

Speaking of paper: a pen — even a Fisher Space Pen — is of little use without paper (unless you are willing to write on your palm or the back of your hand, something I do only in extreme situations). I’m a big fan of Moleskine notebooks and I would love to have one available everywhere I am. Unfortunately, even the small version is too big and heavy to carry in a shirt or pants pocket. By contrast, my ‘emergency notebook’ is quite lightweight: a folded A6 index card, which gives me four pages of about 10 cm x 7.5 cm. It’s not much — but it is something!

Whether there is something to fix or an idea to be jotted down, with my tools I can rise to the occasion; I wouldn’t even think about leaving my house without them.

Reply To All

It simply had to happen again: an unfortunate coworker responded to a department Christmas party invitation, but instead of selecting “Reply” he accidentally chose “Reply to All”. Now 200 people not only know that he will join but also what particular meal he prefers.

Not a big deal, you think?

Years ago, I was on a team facing schedule problems. Our team lead sent an email to our sales manager trying to explain the technical difficulties that we were facing; the whole development and sales team was on the “CC” list. One of the developers replied to the team lead, indicating that a person like our sales manager would never understand our technical problems.

Well, he didn’t use the exact same words that I just used; in fact, he used quite different, actually, rather — ahem — colorful words to express his feelings about the technical abilities of our sales manager. And — you guessed it — he inadvertently clicked on “Reply to All”.

In my view, the one who really is to blame when something happens like this is the company that develops such bad user interfaces. Actually, I don’t know a single mail client that has some level of protection against such embarrassing scenarios.

Here is my solution: When the user selects “Reply To All” change the color of the background to red (or make a beep or some other noticeable change to the look and feel); most importantly, replace the text of the “Send” button with “Send to All”.

Advanced Programming

Today, Hartmut, a colleague, showed me some code written by one of his teammates. He found the code to be very confusing — in fact, he was quite upset about it and the author — and asked me whether I had ever seen tricky code like this.

Oh well, oh well, I had. In fact, I was the one who introduced this particular technique to the author and recommended using it.

Years ago, I had a similar problem on a C++ project. My teammates were not really experienced C++ developers and didn’t know much about templates. As a matter of fact, I like templates and if used with care, they can make the code more readable and maintainable.

But this was just my view — the view of the rest of the team was, well, quite different.

I was shocked and disappointed. I thought I had written great code, but my ignorant colleagues didn’t like it — they didn’t even bother to learn about advanced C++ topics!

Hartmut argued that I’m allowed to use any advanced feature or technique I want as long as the rest of the team understands it. Not satisfied with his advice I countered by explaining that I didn’t want to drive a Ferrari by only using first gear. Hartmut’s response was a complete revelation: “Then”, he said “you have to teach them how to drive a Ferrari using all gears”.

Let me summarize this as ‘Hartmut’s Law of Advanced Programming’:

“You may only use an advanced programming language feature or technique if the rest of the team understands it; if this is not the case and you still want to use it, you have to educate them about it.”

The Policy

I have witnessed the following scenario many times in my life - sometimes it happened to me, sometimes to some colleague. It always goes like this:

1. A company wants to protect itself against loss of something very important (e. g. company reputation, money, life); some prominent people sit together and devise a strict policy for everyone to follow.

2. The policy is cumbersome, so over time, people either ignore it (at least every now and then) or clever people find loopholes and work around it.

3. Years go by; by sheer luck nothing really bad happens.

4. Someday, someone (maybe a new colleague) discovers the truth and in a rush of creativity comes up with a smart and simple solution that achieves 99% of the desired effect while at the same time keeping those who have to use it happy.

5. The idea is rejected by management on the grounds that a) the proposed solution is not perfect either and b) the original policy can’t be so bad as nothing really bad has happened so far!

6. Our once-proud hero gets frustrated.

Why is this obviously good idea rejected? Answer: for political reasons!

Even though our inventor had the best intentions, by suggesting a new approach he caused a lot of problems to many people. He indirectly claimed that:

1. There has been a big threat over years.

2. There are people in the company who haven’t followed management’s policies for years.

3. The designers of the original policy did a poor job.

4. The managers failed to see the obvious: the policy is cumbersome and hard to follow.

5. The managers failed to ensure that the policy is actually followed.

6. He is much smarter than others (i. e. his managers).

Had the new approach been accepted, management would have admitted all these “accusations”. Now it should be clear why the idea was dismissed.

The Three Most Important Tools of a Software Developer

What are the most important tools of a software developer? In my view, the keyboard, a programmer’s editor and a scripting language are the top candidates. Compared to fancy design tools they might look mundane - but only at first sight: combined and mastered, they have the potential for making a developer an order of magnitude more efficient.

KEYBOARD

Let’s face it: as a software developer, you spend most of your time writing. Not just code but also test scripts, documentation and email. Hence, the keyboard is your most important basic tool, just like the saw is the most important basic tool of a carpenter.

It is a sad fact that many programmers don’t master touch typing and instead use the “Hunt and Peck” approach: they awkwardly enter text through slow and error-prone two-fingered typing.

The main problem with two-fingered typing is that since it is so cumbersome and slow, developers tend to avoid writing: they won’t write the Perl prototype of an application that would be so useful for the next trade fair and they certainly won’t write comprehensive documentation. Today, a large part of the communication in software projects happens through email, especially if the team is distributed over the globe - what a pity if you cannot type efficiently!

If you cannot touch-type as a programmer, you simply have to learn it. Now.

Fortunately, it’s rather easy. Within a couple of weeks you can achieve marvelous results by just practicing 20 minutes a day. There are countless programs for self-study out there, many of which are free, like KDE’s KTouch. Just do a search on your favorite search engine for “touch typing”. There are even games, like typespeed that you can use to improve your typing skills. Try it out, it’s great fun! However, it is important that you finish a systematic course first; that is, you know the positions of the basic keys blindfolded.

Once you are sufficiently proficient with the basic keys, you should tackle the remaining special keys as well, since they are quite important for software developers: punctuation marks, the ‘at’ sign, braces and brackets. Don’t stop until you know your keyboard inside out. If you catch yourself peeking at the keyboard too often, consider buying a keyboard with blank keys, like DAS Keyboard: a piano player doesn’t need letters on her keyboard and neither do you.

PROGRAMMER’S EDITOR

For years I had used various editors and IDEs for my daily work: for Java development, I used Eclipse, for C++ development Visual Studio, for batch file and test development as well as log file viewing and editing UltraEdit and TextPad; I used Outlook and Lotus Notes for composing emails and usually Microsoft Word for any other kind of documentation. Even though I read the Pragmatic Programmer’s advise “Use a single editor well”, I didn’t know how to live by it - until a colleague gave me a nice tour of the VIM editor about three years ago.

Ever since that day, my developer life has changed profoundly. Now, I use VIM for at least 90% of my writings. I even use it for composing emails, provided I expect my email to be longer than three lines of text. It’s just sooo cool! Now more do I use IDEs for building my projects; instead, I build from withing VIM by invoking a command-line build script; VIM’s “quickfix” feature lets me easily navigate between compiler warnings and errors. For me, the only legitimate use of an IDE is when doing source-level debugging; for changing the code and compiling I switch back to VIM.

I’m not trying to convince you to to learn VIM, since it is a large investment. It took me a couple of month to get some proficiency and even after three years, I’m still learning. But what a worthwhile investment it is for me!

Whatever editor you chose as your single editor, make sure you know it inside-out. Always ask “is there a smarter, more efficient way to accomplish what I want?” and check with the documentation. For instance, you should know how to program it, know how to create abbreviations and shortcuts, know how to record macros. Find out how to run external tools (like executing makefiles or checking out code from version control). Most importantly, learn all the hotkeys and key combinations for tasks that occur frequently, like deleting the word under the cursor (in VIM type ‘daw’) or indent the current paragraph (in VIM type ‘>ip’).

A programmer’s editor corresponds to a carpenter’s workbench: It serves as an integration platform for all your work.

SCRIPTING LANGUAGE

Even a craftsman sometimes needs power-tools to save time and get mundane and repetitive jobs done; so does the programmer and that’s where scripting languages excel.

By scripting languages I mean dynamic languages like Perl, Python or Ruby that don’t use static type checking like traditional languages such as C and Java do. Scripting languages are highly expressive and have constructs that let you achieve miracles in just a few lines of code. As an example, this Perl code

foreach (qx/my_prog.exe/) {
    ++$errors if (/\berror:\b/);
}

executes “my_prog.exe”, captures its output and counts the total number of error messages. If you are like me and think that this is still too long, here is the one-line version:

$errors = grep /\berror:\b/, qx/my_prog.exe/;

Try this in a traditional programming language of your choice and compare the total number of characters typed - expect that it will be 10 to 20 times as as many.

Most of the time, you will use scripting languages for automation and text processing; however, you can also use it to sketch and smear in order to develop prototypes that you might later recode in a traditional programming language.

A mastered scripting language is a great time-saver: It enables you to write lots of little utilities that make your and your colleagues life easier.

CONCLUSION

The combined power of touch-typing, a programmer’s editor and a scripting language makes a software developer much more productive in two respects: first, it ensures that jobs get done in little time and second, it encourages programmers to try out ideas. The latter is the basis for long-term developer motivation and outstanding performance.

A C Preprocessor Trick

[Warning: Low-level C stuff ahead!]

Imagine a situation where you want to statically initialize an array with values different to 0:

#define ARRAY_SIZE 8
int MY_ARRAY[ARRAY_SIZE] = {
    42, 42, 42, 42, 42, 42, 42, 42
};

This approach works, at least until someday you want to increase the array size to, say, 200. In this case, you have to add 192 times “42, ” to the initializer list. What a dread!

Everything would be easy, if you wanted to zero-initialize the array:

#define ARRAY_SIZE 200
int MY_ARRAY[ARRAY_SIZE] = { 0 };

With zero-initialization, all you have to do is specify the value of the first element - all of the remaining elements will automatically be set to zero.

But sometimes you need a value different to 0 and you don’t want an additional call to “memset()” at run-time. Or you cannot use “memset()” because your array is stored in a read-only ROM segment and you cannot change the array’s values dynamically.

Basically, what you want is this:

#define ARRAY_SIZE 200
int MY_ARRAY[ARRAY_SIZE] = {
    STATIC_INIT(42, ARRAY_SIZE)
};

Then, you would only have to make a single change to alter the size of the array (or the initialization value).

Alas, it turns out that it is impossible to define a macro that does the job we expect from “STATIC_INIT”. Think about it for a while. How would you solve this problem?

Sometimes, it is possible to replace a call to an impossible macro with the inclusion of a header file; I call this technique the “Replace macro call with file inclusion” trick:

#define ARRAY_SIZE 200
int MY_ARRAY[ARRAY_SIZE] = {
    #define STATIC_INIT_VALUE 42
    #define STATIC_INIT_COUNT ARRAY_SIZE
    #include "static_init.h"
};

The two defines represent the macro parameters and the inclusion of the header file represents the actual macro call.

You probably wonder what the contents of “static_init.h” are, but it’s instructive to spend some time on this problem yourself. Afterwards, you can have a look at my solution.

Note that this approach is not limited to single values - you can also use it for more complex initializations. For instance, if you need an alternating sequence of ‘42′ and ‘13′ you would do this:

#define ARRAY_SIZE 200
int MY_ARRAY[ARRAY_SIZE] = {
    #define STATIC_INIT_VALUE 42, 13
    #define STATIC_INIT_COUNT (ARRAY_SIZE / 2)
    #include "static_init.h"
};

I’ve also used the “Replace macro call with file inclusion” trick to encapsulate #pragmas and other compiler-specific features. Consider the case where you are working on a multi-platform project that uses different compilers. Consider further that you have a piece of code that generates compiler warnings and you want to locally turn compiler warnings off:

#pragma warning off
    ...
    // nasty code
    ...
#pragma warning on

Now the problem with this approach is that #pragmas are compiler-dependent, which means that you will end up with something like this:

#if COMPILER1
#pragma warning off
#elif COMPILER2
#pragma nowarn -save
#elif COMPILER3
#nowarn
#else
#error Compiler not supported.
#endif
    ...
    // Nasty code
    ...
#if COMPILER1
#pragma warning on
#elif COMPILER2
#pragma nowarn -restore
#elif COMPILER3
#warn
#else
#error Compiler not supported.
#endif

Not only does this litter the code - it is also a maintenance nightmare.

Usually, the solution is to encapsulate compiler specific features in #defines; alas this obvious strategy doesn’t work for #pragmas:

#define WARNINGS_ON #pragma nowarn -save        // doesn't work
#define WARNINGS_OFF #pragma nowarn -restore    // doesn't work

So it is time to roll out our trick once again:

#include "warnings_off"
    ...
    // Nasty code
    ...
#include "warnings_on"

Where, for instance, “warnings_off” looks like this:

// warnings_off
#if COMPILER1
#pragma warning off
#elif COMPILER2
#pragma nowarn -save
#elif COMPILER3
#nowarn
#else
#error Compiler not supported.
#endif

You probably won’t need this trick very often, but when you do, it is good to know that it’s there.

The Awful Java Programming Language

In 1880, Mark Twain wrote a satirical essay entitled “The Awful German Language” where he explains his difficulty in getting the hang of the complicated German grammar. Today, I felt like it was time for me to nag a little bit about the Java programming language.

Don’t get wrong - I’m actually a Java fan. Years ago, I took (and successfully passed) the “Java Certified Developer” exam; I’ve written a considerable amount of Java code in my life. I’ve always loved Java for its run-time environment: the platform-independence you get from the virtual machine and the huge set of powerful libraries. I’m not complaining about Java per se - I’m only complaining about the Java programming language.

Obviously, it’s easy to find weak spots in any programming language - that’s why there are so many of them. Today, I only want to focus on one thing - Java’s wordiness, or rather, Java’s lack of expressiveness.

When developing software, I often start out with a Perl prototype. Yes, Perl is a quirky language, but it is also very powerful and most of its power comes from its very expressive grammar. It is easy to get your job done with Perl.

The other day, I was working on a seemingly simple problem, along these lines: a server produces a text file, containing user vs. usage-time records:

    # Format:  <user> <time>
    # Asterisk: secure connection used.
    Alice 13
    John 440
    Bob 2
    Carl 49
    * Peter 90
    Alice 219
    Bob 8
    Alice 72
    * Jim 1
    Peter 97
    Jim 199

Another process - my program - takes this list as input, sums up all the usage-times for a user and prints an alphabetically sorted list:

    Alice:304
    Bob:10
    Carl:49
    Jim:200
    John:440
    Peter:187

That’s it. Sounds like a five minute job, which it is, if you happen to use Perl:

    open USERS, "users" or die "Cannot access user list\n";
    while (<USERS>) {
        next if /\s*#/;
        $users{$1} += $2 if /^\*?\s*(\w+) (\d+)/;
    }

    print "$_:" . $users{$_} . "\n" foreach (sort keys %users);

But since I needed this functionality as part of a larger Java product, I bravely recoded it in Java:

    public class GetUsers {
        public static void main(String argv[]) {
            HashMap map = new HashMap();
            try {
                String line;
                BufferedReader input = new BufferedReader(new FileReader("users"));
                Pattern pattern = Pattern.compile("^\*?\s*(\w+) (\d+)");
                while ((line = input.readLine()) != null) {
                    if (Pattern.matches("^\s*#.*$", line))
                        continue;
                    Matcher matcher = pattern.matcher(line);
                    if (matcher.find()) {
                        Integer i = map.get(matcher.group(1));
                        int origVal = (i != null) ? origVal = i.intValue() : 0;
                        int addVal = Integer.parseInt(matcher.group(2));
                        map.put(matcher.group(1), origVal + addVal);
                    }
                }
            }
            catch (Exception err) {
                err.printStackTrace();
            }

            Object[] keys = map.keySet().toArray();
            Arrays.sort(keys);
            for (Object s : keys) {
                System.out.println(s + ":" + map.get(s).intValue());
            }
        }
    }

Wow! I used the regular expression library and the HashMap container class; I even used Java 5’s autoboxing feature as well as generic containers (both of which save you a lot of casting); nevertheless, the Java version has almost four times more lines than my Perl script. Here are the stats:

    Language:  Perl  Java  Ratio
    Lines:     9     35    3.9
    Chars:     214   1365  6.4

The figures for the number of characters are even worse: the Java program required six times more typing.

Is this additional typing really such a big problem? It definitely is! Studies have shown that the number of lines written per developer per time-unit is by and large independent of the programming language used, which means that you are three to four times more productive in Perl than you are in Java. But there is another angle to this problem: if your programming language is highly expressive (like Perl, Python, and Ruby) you are many times more likely to actually write programs. You cannot imagine how many useful programs I have written in Perl that I would have never written in C/C++/Java - just because of all that typing!

I’ve never liked Sun’s “it-is-so-simple-even-a-brain-dead-monkey-can-now-program” paradigm. As a professional software developer - just like a craftsman - I need powerful tools: tools that get the job done in as little time as possible. These tools might be dangerous - very much like a power drill or a circular saw - but in the hands of an expert they can achieve miracles.

But Perl is not perfect, either. Hmmm…. I know what I’m going to do next: I’ll just follow the pragmatic programmer’s advice: “learn a new programming language every year”. This time I will check out “Groovy“, a programming language that - according to a recent article that appeared in a popular German computer magazine - combines all the advantages of Perl, Python, Ruby and - Java. Great! I’ll just order a textbook from Amazon. I will keep you updated on my journey. Stay tuned…

Spec Coders

If you’ve been working as a professional software developer for some time, you must have come across a “Spec Coder”.

Spec Coders are usually well-educated, have good grades and know every detail about dozens of specs. Frequently, they come with social skills well above the level of the average (nerdy) coder. They are - therefore - a human resource manager’s dream.

Alas, what they can’t do is write decent code, I mean, readable, reusable, efficient, elegant code. Sure, they’ve read “Kernighan & Ritchie” and they might have taken a three-day Java course, but between their excellent domain knowledge and their (basic) knowledge of a programming language is a big gap in every Spec Coder: a total lack of design capabilities due to a total lack of passion for software development.

This lack of passion clearly shows in their “if-this-do-that-else-do-another-thing” style of programming. You won’t find abstractions, base classes, function pointers, recursion. Just a plain translation of boring spec words into code that sucks.

Here’s an example.

Let’s assume our Spec Coder is assigned the task to write some code for a file system and that THE SPEC says:

3.2 File selection behavior

After selecting a file, the file’s record marker shall be undefined, except for ‘blue’ files, in which case the record marker shall point to the first file record.

Our Spec Coder will immediately turn this into code like this (don’t worry about the use of global variables here - it’s just an example):

void SetCurrentFile(FILE_REF ref, FILE_TYPE type)
{
    ...
    g_CurrentFile = ref; 

    if (type != FILE_TYPE_BLUE) {
        // Record marker undefined.
        g_CurrentRecord = -1;
    }
    else {
        // Record marker at first record.
        g_CurrentRecord = 0;
    }
    ...
}

So far so good, at least until someday THE SPEC gets extended (obviously by a non-programmer):

3.2 File selection behavior

After selecting a file, the file’s record marker shall be undefined, except for ‘blue’ files, in which case the record marker shall point to the first file record.
If the file system is in state ‘raw’, the record marker shall always be undefined.

Again, the Spec Coder will directly translate this to code:

    ...
    g_CurrentFile = ref;
    if (type != FILE_TYPE_BLUE) {
        g_CurrentRecord = -1;
    }
    else {
        g_CurrentRecord = 0;
    }
    if (g_FileSysMode == FILE_MODE_RAW)
    {
        g_CurrentRecord = -1;
    }
    ...

How disgusting! Our Spec Coder didn’t take the time to refactor the code logic according to the new requirement. In fact, a typical Spec Coder wouldn’t even think that refactoring this code was a sensible thing to do. Why? Because there wouldn’t be a 1:1 mapping between the code and THE SPEC anymore. Arrrgh!

Any true software developer would have jumped at the chance. A true software developer would have mentally rephrased THE SPEC to read “A file’s record marker is always undefined, except for ‘blue’ files when the system state is not ‘raw’”:

    ...
    g_CurrentFile = ref;
    g_CurrentRecord = (g_FileSysMode != FILE_MODE_RAW && type == FILE_TYPE_BLUE) ? 0 : -1;
    ...

This code is definitely more efficient and readable. If you don’t like the ternary operator, just use an if-else statement (are you a Spec Coder, by any chance?):

    ...
    g_CurrentFile = ref;
    g_CurrentRecord = -1;
    if (g_FileSysMode != FILE_MODE_RAW && type == FILE_TYPE_BLUE) {
        g_CurrentRecord = 0;
    }
    ...

Are Spec Coder’s really dangerous? I think so! Because of their attitude, with every change they make, the code gets slightly more complicated - little by little - until it’s such a mess nobody understands anymore. Once the critical mass is reached, even otherwise decent developers tend to implement their changes by adding little “ifs” here and there. But there is another problem with Spec Coder’s: It is usually difficult to get rid of them, because their usually good spec knowledge makes them indispensable for a company.

Weird, isn’t it?

Douglas Adam’s Cookies

I recently read a funny story by Douglas Adams called “Cookies“.

Here is a summary.

Douglas arrives early for a train, and buys a cup of coffee, a newspaper and a packet of cookies. He takes a seat at a table, opposite of a businessman. After a while, the guy leans forward grabs the packet of cookies, tears it open and eats one. In his story, Douglas explains how he - as an Englishman - is not at all able to cope with this situation, so he just takes a cookie himself. A minute later, the guy takes another cookie and so does Adams. This procedure repeats until the packet is empty. Finally, the guy leaves - they both exchange “meaningful looks”. When the train arrives, Adams gets up, takes his newspaper and discovers underneath it - his packet of cookies! Douglas ends the story by saying that “The thing I like particularly about this story is the sensation that somewhere in England there has been wandering around for the last quarter-century a perfectly ordinary guy who’s had the same exact story, only he doesn’t have the punch line.”

A very funny story, indeed…

After my giggling had settled, I couldn’t stop pondering about it. Doesn’t this seemingly improbable story happen all the time, only slightly differently? How often do we think somebody is plain wrong or is unfair to us, when in fact it is exactly the other way around? How often do engineers, salespeople and managers talk at cross purposes? Isn’t this a terrible good example of a paradigm shift, a total change in one’s perspective?

Douglas picked up the newspaper, which triggered the paradigm shift. If he hadn’t picked up the newspaper, he would have walked around for the rest of his life believing that the other guy was pretty weird. So what is the lesson to be learned? Whenever we think we are treated badly or others are plain wrong, we should try hard to find the newspaper — and pick it up.