Professionalism in Programming, from CVu journal + CVu Journal Vol 16, #4 - Aug 2004
Browse in : All > Journal Columns > Professionalism
All > Journals > CVu > 164
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: Professionalism in Programming #27

Author: Administrator

Date: 03 August 2004 13:16:07 +01:00 or Tue, 03 August 2004 13:16:07 +01:00

Summary: 

Body: 

Is it that time already? This is the 27th column in the professionalism series. It's been running for 4½ years now, in which time it's established itself as a part of the furniture. You either take it for granted and have learnt to carefully ignore it, or you diligently read and inwardly digest every word. Well, now it's time to break with tradition, and also to see how much attention you've been paying all these years.

The series index beside this article provides an overview of the secluded tributaries we've explored in the vast software development waterways. In this article we'll revisit some of this ground in a more interactive manner. It's your chance to see how 'professional' you really are.

Here's the game plan: for a few of these past topics I have posed some thought-provoking questions for you to mull over. Some are purely factual, some are more personal, probing your personal development practices and those of the team you work in. Consider them and answer as fully and honestly as you can. Then turn to the end of the article, where I provide my musings on each question. I won't be so bold as to claim this is a definitive answer set, but more of a gentle exploration of each problem.

You'll only get out of this exercise as much as you're prepared to put in. So grab a cup of coffee, find a comfy chair in a quiet corner, and it's eyes down for a full house…

Questions

First, here are the questions. Spend a while considering your answer to each one before you move on to the following section.

Defensive Programming (C Vu 13.5, August 2001)

In this article we looked at the need for a 'defensive' approach to programming, learnt to assume nothing, and investigated some practical defensive coding techniques. We saw how to use constraints effectively, as typified by C's assert macro. However:

  1. Could there be such a thing as too much defensive programming?

  2. Should assertions conditionally compile away to nothing in production builds? If not, which assertions should remain in release builds?

  3. Should the defensive checking of pre- and postconditions be put inside each function, or beside each important function call?

  4. Are constraints a perfect defensive tool? What are their drawbacks?

  5. Can you avoid defensive programming?

    1. If you designed a better language, would defensive programming still be necessary? How could you do this?

    2. Does this show that C and C++ are flawed because they have so many areas for problems to manifest?

  6. What sort of code need you not worry about writing defensively?

  7. When you document a function, do you state the pre- and postconditions?

    1. Are they always implicit in the description of what it does?

    2. If there are no pre/postconditions do you explicitly document this?

  8. Many companies pay lip service to defensive programming. Does your team recommend it? Take a look at the code base - do they really? How widely are constraints codified in assertions? How thorough is the error checking in each function?

  9. Are you naturally paranoid enough? Do you look both ways before crossing the road? Do you eat your greens? Do you check for every potential error in your code, no matter how unlikely?

    1. How easy is it to do this thoroughly? Do you forget to think about errors?

    2. Are there any ways to help yourself write more thorough defensive code?

Layout of Source Code (C Vu 12.2, April 2000)

This first ever professionalism column looked into the contentious topic of source code layout, demonstrating that consistency is more important than any one particular coding style. We concluded that holy wars over topics like this are pointless and unprofessional. So:

  1. Should you alter the layout of legacy code to conform to your latest code style? Is this a valuable use of code reformatting tools?

  2. One common layout convention is to split source lines at a set number of columns. What are the pros and cons of this approach?

  3. How detailed should a reasonable coding standard be?

    1. How serious are deviations from the style? How many limbs should be amputated for not following it?

    2. Can such a specification become too detailed and restrictive? What would happen if it did?

  4. Is good code presentation or good code design more important? Why?

  5. Do you write in a consistent style?

    1. When you touch other people's code, what layout style do you adopt - theirs or your own?

    2. How much of your coding style is dictated by your editor's autoformatting? Is this an adequate reason for adopting a particular style?

  6. Tabs: are they a work of the devil, or the best thing since sliced bread? Explain why.

    1. Do you know if your editor inserts tabs automatically? Do you know what your editor's tab stop is?

    2. Some hugely popular editors indent with a mixture of tabs and spaces. Does this make the code any less maintainable?

    3. How many spaces should a tab correspond to?

  7. Grab a text editor and have a go at this bit of C++, it calculates the nth prime number. It's written in one particular coding style. Have a crack at presenting it as you'd like to see it. Don't try to change the implementation at all.

    /* Returns whether num is prime. */
    bool
    isPrime(int num ) {
        for ( int x = 2; x < num; ++x ) {
          if ( !(num % x ) ) return false;
        }
        return true;
    }
    
    /* This function calculates the 'n'th prime
       number.*/
    int
    prime( int pos ) {
        if ( pos ) {
            int x = prime( pos-1 ) + 1;
            while ( !isPrime( x ) ) {
                ++x;
            }
            return x;
        } else {
            return 1;
        }
    }
    

What's in a Name? (C Vu 14.5, October 2002)

This article showed the impact of good naming on the quality of our source code, and demonstrated practical naming techniques for many common code constructs. What do you think about these issues:

  1. Are these good variable names? Answer with either yes (explain why, and in what context), no (explain why), or can't tell (explain why).

    1. int num_apples

    2. char foo

    3. bool num_apples

    4. char *string

    5. int loop_counter

  2. When would these be appropriate function names? What return types/parameters might you expect? What return types would make them nonsensical?

    1. doIt(...)

    2. value(...)

    3. sponge(...)

    4. isApple(...)

  3. Should a naming scheme favour the easy reading or easy writing of code? How would you make either easy?

  4. What do you do when naming conventions collide? Say you're working on camelCase C++ code, and need to do STL (using_underscore) library work. What's the best way to handle this situation?

  5. If assert is a macro why is its name lower case? Why should we name macros so they stand out?

  6. Long calculations can be made more readable by putting intermediate results in temporary variables. Suggest good naming heuristics for these types of variable.

  7. Do you have to port code between platforms? How has this affected filenames, any other naming, and the overall code structure?

A Passing Comment ( C Vu 15.2, April 2003)

The final article we'll exhume looked at how to write code comments. We learnt what makes a good comment, how to avoid pointless and intrusive comments, and how to use comments to help us write source code. Given this, then:

  1. How might the need for and the content of comments differ in the following types of code:

    1. Low level assembly language (machine code)

    2. Shell scripts

    3. A single file test harness

    4. A large C/C++ project

  2. You can run tools to calculate what percentage of your source code lines are comments. How useful are they? How accurate a measure is this of comment quality?

  3. When you document a C/C++ API with a code comment block, should it go in the public header file that declares the function, or the source file containing the implementation? What are the pros and cons of each location?

  4. Look carefully at the source files you've recently worked on. Inspect your commenting. Is it honestly any good? (I bet as you read through the code you'll find yourself making a few changes!)

  5. How do you ensure that your comments are genuinely valuable and not just personal ramblings that only you can understand?

  6. Do the people you work with all comment to the same standard, in about the same way?

    1. Who's the best at writing comments? Why do you think that? Who's the worst? How much of a correlation does this bear to their general quality of coding?

    2. Do you think any imposed coding standards could raise the quality of the comments written by your team?

  7. Do you include history logging information in each source file? If yes:

    1. Do you do maintain it manually? Why, if your revision control system will insert this for you automatically? Is the history kept particularly accurate?

    2. Is this a really sensible practice? How often is this information needed? Why is it better placed in the source file than in another, separate mechanism?

  8. Do you add your initials to or otherwise mark the comments you make in other people's code? Do you ever date comments? When and why do you do this - is it a useful practice? Has it ever been useful to find someone else's initials and time stamping?

Discussion and Answers

Lazy readers will have jumped here already. Please do spend some time considering your answer to each question first. It will be interesting to compare your response with mine. Do you disagree with anything? Do you agree? Let me know.

Defensive Programming

  1. Could there be such a thing as too much defensive programming?

    Yes - just as too many comments can degrade code readability, so too can many defensive checks. Redundant checks can be avoided with careful coding, for example with a good choice of types.

  2. Should assertions conditionally compile away to nothing in production builds? If not, which assertions should remain in release builds?

    People hold passionate beliefs on this subject. I don't think the answer is necessarily black and white; I can see the argument both ways. There are always some very nit-picky assertions that really won't need to be left in production builds. But some assertion occurrences may still interest you in the field. Now, if you do leave any constraint checks in, they must change behaviour - the program shouldn't abort on failure, just log the problem and move on.

    Remember, real run-time error checks should never be removed; they should never be coded in assertions anyway.

  3. Should the defensive checking of pre- and postconditions be put inside each function, or beside each important function call?

    In the function, without a doubt. This way, you only need to write tests once. The only reason you'd want to move them out is to gain flexibility, to choose what happens when a constraint fails. This isn't a compelling gain for such an explosion in complexity and potential for failure.

  4. Are constraints a perfect defensive tool? What are their drawbacks?

    No, they are nowhere near perfect. Redundant constraints can be at best a pest, and at worst a hindrance. For example, you could assert that a function parameter i >= 0. But it's much better to make i an unsigned type that can't contain 'invalid values' anyway.

    Treat constraints that can be compiled out with a certain degree of suspicion: we must carefully check for any side effects (assertions can have subtle indirect consequences), and for timing issues in the debug build that alters its behaviour from a release build. Ensure that assertions are logical constraints and not genuine run-time checks that mustn't be compiled out. It is possible to put bugs in the bug-defence code!

    Carefully used, constraints are still far better than dancing barefoot over the hot coals of chance.

  5. Can you avoid defensive programming?

    1. If you designed a better language, would defensive programming still be necessary? How could you do this?

    2. Does this show that C and C++ are flawed because they have so many areas for problems to manifest?

    Some language features certainly could be designed to avoid errors. For example, C doesn't check the index of any array lookup you perform. As a result you can crash the program by accessing an invalid memory address. The Java runtime, on the other hand, checks every array index before lookup, so such an catastrophe will never arise. (Bad indexes will still cause an error though, which is just a better defined class of failure).

    Despite the long list of 'improvements' you could make to the liberal C specification (and I urge you to think of as many as you can) you'll never be able to create a language that doesn't need defensive programming. Functions will always need to validate parameters, and classes will always need invariants to check their data is internally consistent.

    Although C and C++ do provide plenty of opportunity for things to go wrong, they also provide a great deal of power and expression. Whether that makes the languages 'flawed' depends on your viewpoint - this is a topic ripe for holy war.

  6. What sort of code need you not worry about writing defensively?

    I've worked with people who refused to put any defensive code into an old program because it was so bad that their defences would make no difference. I managed to resist the urge to whack them with a large mallet!

    You might argue that a small, stand-alone, single file program or perhaps a small test harness file doesn't need this sort of careful defensive code or any rigorous constraints - but even in these situations not being careful is just being sloppy. We should be defensive all the time.

  7. When you document a function, do you state the pre- and postconditions?

    1. Are they always implicit in the description of what it does?

    2. If there are no pre/postconditions do you explicitly document this?

    No matter how obvious you think a contract is from the function name or its description, explicitly stating the constraints removes any ambiguity - remember, it's always better to remove areas of assumption. Explicitly writing Preconditions: None will document a contract explicitly.

  8. Many companies pay lip service to defensive programming. Does your team recommend it? Take a look at the codebase - do they really? How widely are constraints codified in assertions? How thorough is the error checking in each function?

    Very few companies have a culture of excellent code with the right level of defence. Code reviews are a good way to bring a team's code up to a reasonable standard; many eyes see many more potential errors.

  9. Are you naturally paranoid enough? Do you look both ways before crossing the road? Do you eat your greens? Do you check for every potential error in your code, no matter how unlikely?

    1. How easy is it to do this thoroughly? Do you forget to think about errors?

    2. Are there any ways to help yourself write more thorough defensive code?

    No one finds it naturally easy - thinking the worst of your carefully crafted new code runs contrary to the programmer instinct. Instead, expect the worst of any people who will be using your code. They're nowhere near as conscientious a programmer as you!

    A very helpful technique is to write unit tests for each function/class. Some experts strongly advise doing this before writing a function; this makes a lot of sense. It helps you to think about all the error cases, rather than blithely trusting that your code will work.

Layout of Source Code

  1. Should you alter the layout of legacy code to conform to your latest code style? Is this a valuable use of code reformatting tools?

    It's usually safest to leave legacy code however you find it, even if it's ugly and hard to work with. I'd only entertain reformatting if I was absolutely sure that none of the original authors would ever need to return.

    By reformatting you lose the ability to easily compare a particular revision of the source with a previous one - you'll be thrown by many, many, formatting changes which may hide the one difference you really needed to see. You also risk introducing program errors in the reformatting.

    As far as code reformatting tools go, they're nice curiosities, but I don't advocate the use of them. Some companies insist on running source files through these tools before checking any code into their repository. The advantage is that all source is homogenised, pasteurised, and uniformly formatted. The major disadvantage is that no tool is perfect; you'll lose some helpful nuances of the author's layout. Unless all the programmers on your team are gibbons, don't use a reformatting tool.

  2. One common layout convention is to split source lines at a set number of columns. What are the pros and cons of this approach?

    As with many such presentation concerns there is no absolute answer; it is a matter of personal taste.

    I like to split my code up so that it fits on an 80 column display. I've always done that, so it's a matter of habit as much as anything else. I don't disagree with people who like long lines, but I find long lines hard to work with. I set my editor up to 'wrap' continuous lines rather than provide a horizontal scrollbar (horizontal scrolling is clumsy). In this environment long lines tend to ruin the effect of any indentation.

    As I see it, the main advantage of fixed column widths is not printability, as some would claim. It's the ability to have several editor windows open side-by-side on the same display.

    In practice, C++ seems to produce very long lines. It's more verbose than C; you end up calling member functions on objects referenced by another object through a templated container... There are other strategies to manage the many, many, long lines this may lead to. You could store intermediate references in temporary variables, for example.

  3. How detailed should a reasonable coding standard be?

    1. How serious are deviations from the style? How many limbs should be amputated for not following it?

    2. Can such a specification become too detailed and restrictive? What would happen if it did?

    Six limbs should be amputated for deviations from any coding standard.

    I have seen many coding standards that are so prescriptive and paralysing that the poor programmers have just plain ignored it. To be useful, and to be accepted, a coding standard should provide a little room for manoeuvre, perhaps with a best practice approach given as an example.

  4. Is good code presentation or good code design more important? Why?

    This is really a very artificial question. Both are fundamental for good code, and you should never be asked to sacrifice one for the other. If you ever are, fear. However, which one you just chose may say a lot about you as a programmer.

    Bad formatting is certainly easier to fix than bad design, especially if you use clever tools to homogenise your code's formatting.

    There is an interesting connection between presentation and design: Bad presentation often shows that the code was produced by a bad programmer, which probably means that it suffers from bad internal design too. Or it may imply that the code has been maintained by a series of different programmers, with a subsequent loss of the initial code design.

  5. Do you write in a consistent style?

    1. When you touch other people's code, what layout style do you adopt - theirs or your own?

    2. How much of your coding style is dictated by your editor's autoformatting? Is this an adequate reason for adopting a particular style?

    If you can't alter the way your editor positions the cursor for you then you shouldn't be using it (either you're too inept, or your editor is).

    If you can't write code in a consistent style then you should have your programmer's licence revoked. If you can't follow someone else's presentation style then you should be forced to maintain BASIC for the rest of your career.

    [FORTRAN 77 is far more restrictive on its code style and formatting. Depending on the flavour of BASIC, style and format can be varied greatly - Ed]

  6. Tabs: are they a work of the devil, or the best thing since sliced bread? Explain why.

    1. Do you know if your editor inserts tabs automatically? Do you know what your editor's tab stop is?

    2. Some hugely popular editors indent with a mixture of tabs and spaces. Does this make the code any less maintainable?

    3. How many spaces should a tab correspond to?

    Since this is such a religious issue, I'll just say tabs: they suck and back away quickly. Well, actually I'll add afterwards that the only thing more evil than indenting with tabs is indenting with tabs and spaces - nightmare!

    If your editor is inserting tabs (and probably spaces) without you noticing, try using another editor for a while, to appreciate how frustrating it is. Try setting your tabstop to a different value and see what a mess it makes of the code. Everyone uses the same editor, so it doesn't matter is not a professional attitude. They don't.

    You'll hear people recommend their choice of tabstop length and carefully justify their opinion. That's all very well; in fact a respected study claims that a three or four space tabstop provides optimum readability. (I favour four spaces because I don't like odd numbers!) However, a tab should 'correspond' to no fixed number of spaces. A tab is a tab, which is not a space or any multiple thereof. For code laid out using tabs, it shouldn't matter exactly how many spaces the tab is displayed as - the code should read well regardless. Unfortunately, I have rarely seen tab-indented code that works this way. All too often tabs and spaces are mixed together to make code line up neatly. This works fine with a tabstop set as the author intended. It makes an unholy mess with any other setting.

  7. Grab a text editor and have a go at this bit of C++, it calculates the nth prime number. It's written in one particular coding style. Have a crack at presenting it as you'd like to see it. Don't try to change the implementation at all.

    This is a representative bit of Real World code, so don't dismiss this as a stupid and tedious exercise. Note that I haven't given any suggested answer here. My reformatting is just as valid as yours, and indeed as the original format.

    If you're reading these answers without chewing over the questions at all, go on - have a go at this one. The magazine can wait whilst you type in a few lines...

    Now, take a look at what you've written.

    • How different is your version? How many specific changes did you make?

    • For each change: is it a personal aesthetic preference, or can you justify the change with some rationale? Question this rationale - is it truly valid? How strongly would you be prepared to defend it?

    • How comfortable were you with the original format? Did it bother you to read? Could you work in that coding style if you encountered code like it? Should you be able to become comfortable with it?

    [I have to admit I found it very difficult to restrain myself from reformatting the code as I processed this article! - Production Ed]

What's in a Name?

  1. Are these good variable names? Answer with either yes (explain why, and in what context), no (explain why), or can't tell (explain why).

    1. int num_apples

    2. char foo

    3. bool num_apples

    4. char *string

    5. int loop_counter

    The quality of a name depends on its context, and we can't honestly tell whether any of these are good or bad names. That's why the question asks for example contexts. There are some obvious contexts where the names might be bad: num_apples wouldn't be a particularly good name for a grapefruit counter.

    foo is never a good name. I've yet to see anyone counting foos. loop_counter is also bad; even if a loop gets too big for a short counter name you can still pick a more descriptive name, one that reflects the actual use of loop counter rather than its role as a loop counter.

    We can't really tell whether bool num_apples is a good name, but it looks like it's not - a boolean cannot hold a number. Perhaps it's recording whether a separate count of apples is valid, but in this case it ought to be called something like is_num_apples_valid.

  2. When would these be appropriate function names? What return types/parameters might you expect? What return types would make them nonsensical?

    1. doIt(...)

    2. value(...)

    3. sponge(...)

    4. isApple(...)

    What each of these might mean depends on where you find them. Again we see how a name depends on its context, and that context can be provided by the enclosing scope of the function. Context information can even be given by function parameters or return variables.

  3. Should a naming scheme favour the easy reading or easy writing of code? How would you make either easy?

    How many times do you write a piece of code? (Think about it). How many times do you read it? That should give some indication as to the relative importances.

  4. What do you do when naming conventions collide? Say you're working on camelCase C++ code, and need to do STL (using_underscore) library work. What's the best way to handle this situation?

    I've worked on C++ codebases that used such a collision of naming conventions to their advantage. The internal logic used camelCase, whereas libraries and components that could be considered extensions of the standard library followed STL naming conventions. It actually worked quite well.

    Unfortunately, it doesn't always work that nicely. I've seen plenty of inconsistent code where there was no rhyme or reason behind the changing styles.

  5. If assert is a macro why is its name lower case? Why should we name macros so they stand out?

    assert isn't capitalised because assert isn't capitalised. In an ideal world it would be, but standards being what they are we have to live with this tatty macro name. Sigh.

    Macros and #defined constant definitions are downright dangerous - adopting the UPPER CASE name convention will prevent nasty collisions with ordinary names. It's as sensible as wearing glasses when a lunatic is walking round with a big pointy stick.

    Because macros can be so painful you should chose names that are very unlikely to cause headaches. More importantly, avoid using the preprocessor as much as humanly possible.

  6. Long calculations can be made more readable by putting intermediate results in temporary variables. Suggest good naming heuristics for these types of variable.

    Bad temporary names are tmp, tmp1, tmp2... or a, b, c... These, unfortunately, are all common intermediate names.

    Like any other item, temporary names should be meaningful. In fact, in a complex calculation good names can really serve to document the internal logic, showing what's going on.

    If you find a value that really has no nameable purpose, if it truly is an arbitrary intermediate value that's hard to name, then you'll begin to understand why tmp is so popular. Avoid calling anything tmp if possible - try to break the calculation in some other way to help it make more sense.

  7. Do you have to port code between platforms? How has this affected filenames, any other naming, and the overall code structure?

    Older filing systems limited the number of characters you could use in a filename. This made file naming much messier. Unless you have to port code to such an archaic system this kind of limitation can be safely ignored.

    File-based polymorphism is a cunning way to exploit filenames to achieve code substitutability at build-time. It's often used to select platform-specific implementations in portable code. You can set up header file search paths, allowing one #include to pull in a different file depending on the current build platform.

A Passing Comment

  1. How might the need for and the content of comments differ in the following types of code:

    1. Low level assembly language (machine code)

    2. Shell scripts

    3. A single file test harness

    4. A large C/C++ project

    Assembly language is less expressive, providing fewer opportunities for self-documenting code. You'd therefore expect more comments in assembly code, and those comments to be at a much lower level than in other languages. Although the golden comment rule is "comments describe why not how", generally assembly comments would explain how as well as why.

    There isn't an enormous a difference between the remaining three. Shell scripts can be quite hard to read back; they are a proto-Perl in this respect. Careful commenting helps. You're more likely to use literate programming techniques on a large C/C++ codebase.

  2. You can run tools to calculate what percentage of your source code lines are comments. How useful are they? How accurate a measure is this of comment quality?

    This kind of metric will give an insight into the code, but you shouldn't get too concerned about it. It isn't an accurate reflection of code quality. Well documented code might not contain any comments. Enormous revision histories or large corporate copyright messages can dominate small files, affecting this metric.

  3. When you document a C/C++ API with a code comment block, should it go in the public header file that declares the function, or the source file containing the implementation? What are the pros and cons of each location?

    This question was the cause of a big fight at one place I worked. Some argued for descriptions to go in the .c file. Being close to the function means that it's harder to write an incorrect comment, and harder to write code that doesn't match the documentation. The comment is also more likely to be changed in line with any code changes.

    However, when placed in a header file, the description is visible alongside the public interface; a logical location. Why should someone have to look into the implementation to read any public API docs?

    A literate programming documentation tool should be able to pull comments out of either place, but sometimes it's quicker not to use the tool and just read comments in the source; a bonus of the literate code approach. I favour placing the comments in header files.

    Of course, in Java it's all one file anyway, and you'd conventionally use the Javadoc format.

  4. Look carefully at the source files you've recently worked on. Inspect your commenting. Is it honestly any good? (I bet as you read through the code you'll find yourself making a few changes!)

    When you read and review your own code it's very easy to skip the comments, presuming they're correct, or at least adequate. It is a good idea to spend some time looking at them, to assess how well they're written. Perhaps you could ask a trusted colleague to give you their (constructive) opinion on your commenting style.

  5. How do you ensure that your comments are genuinely valuable and not just personal ramblings that only you can understand?

    Some considerations for this are: write whole sentences, avoid abbreviations, keep comments neatly formatted, and in a common language (both the native language and the selection of words used from the problem domain). Avoid in-jokes, any throw-away statements, or anything that you're not entirely sure about.

    Code reviews will highlight weaknesses in your comment strategy.

  6. Do the people you work with all comment to the same standard, in about the same way?

    1. Who's the best at writing comments? Why do you think that? Who's the worst? How much of a correlation does this bear to their general quality of coding?

    2. Do you think any imposed coding standards could raise the quality of the comments written by your team?

    Use code reviews to inspect your peers' comment quality, and to move your team towards a consistent quality of commenting.

  7. Do you include history logging information in each source file? If yes:

    1. Do you do maintain it manually? Why, if your revision control system will insert this for you automatically? Is the history kept particularly accurate?

    2. Is this a really sensible practice? How often is this information needed? Why is it better placed in the source file than in another, separate mechanism?

    It's human nature not to keep a history accurate, even with the best intentions in the world. It requires a lot of manual work that gets pushed out when time is tight. You should use tools to help, and put the right information in the right place (which I don't believe is the source file at all).

  8. Do you add your initials to or otherwise mark the comments you make in other people's code? Do you ever date comments? When and why do you do this - is it a useful practice? Has it ever been useful to find someone else's initials and time stamping?

    For some comments this is a useful practice. In other places, it's just inconvenient - extra comment noise that you have to read past to get to the really interesting stuff.

    It's most useful with temporary FIXME or TODO comments, marking work in progress. Released production code probably shouldn't have these; no finished code should need a reader to understand the author or date of a particular change.

And Finally…

Just in case you got this far, here's a parting shot - one final question for a few bonus points. Answer this: How many programmers does it take to change a light bulb?

I have five answers. If you're good then I'll tell you next time. Let me know your answers.

Pete Goodliffe

[With apologies to the ghost of Monty Python for the second vague and fleeting reference of this series. Do you remember the first one?]

Notes: 

More fields may be available via dynamicdata ..