Arnon Rotem-Gal-Oz graciously took time to comment on my post Code comments, b-aaaad. He pointed out his recent post Code readability – Documentation vs. Refactoring, which I’ve had marked to write about. I’d gotten lost in some of the 3.0 issues he write about, though.
I agree with Arnon when he says that “while both of these efforts can help satisfy a customer specific requirement for ‘comprehansive [sic] documentation’ they have very little value in making anyone understand anything about your code.” (Emphasis is his.)
IOW, instead of explaining code, make code explain itself. In my own post I suggest a one week challenge for any readers who remain unconvinced of how much of an improvement even simple and minor refactoring can make. I wrote about looking for comments in longish sections of code, and refactoring with Extract Method. Arnon addresses long sections of code, and he gives a detailed example of how to do it. (Even if you don’t code in C#, it’s instructive.)
I find I’m most often refactoring long sections of code, and that Extract Method is the commonest technique I use. Comments are a useful hint in other situations, though, such as when they state a programming assumption. Instead of commenting assumptions, program an assertion.
It’s easiest for me to find examples in Visual FoxPro code because of its untyped variables, and because parameters are optional. VFP programmers are accommodating folk so we sometimes try to make sense of unexpected parameter types. For example,
IF TYPE("toObject")#"O" OR ISNULL(toObject)
It was only after programming in C# for a time that I realized this spirit of cooperation was flawed. Why? Frequently these functions change behavior depending on what is passed: sometimes subtly, sometimes not so subtly. It’s also confusing to the programmer (even if it’s just our future selves) who is trying to understand either the function or a mysterious error that occurs down stream because we’ve tried to protect the programmer from themselves. A non-VFP programmer expressed disgust with this co-dependent style by saying “sometimes an error should cause, uh, an error.”
I’m a convert, and I’ve long since stopped this practice except in rare and exceptional circumstances. Instead, I let bad parameters throw errors. I have an Intellisense script now that I use whenever writing a function or method. The IS script inserts the following code when I type “badparms”:
Assert Vartype( ) = "C" ;
Message "Did you mean to pass a bad parameter to " + ;
Program( Program(-1) -1 ) + "?"
(Obviously I specify the parameter in Vartype() and change the type (“C”) if need be.)
If I pass a bad parameter and it makes it into the client’s hands, the program will throw (and log) the error. When I run the code while debugging or testing, the Assert will help me debug the places I call the function incorrectly.
So, while you’re looking for comments (hello, hello, is this thing on?) look for ones that you can replace with an assertion. It will document the assumption and help you debug.