The Natural Language Naming Convention
Avoid comments whenever possible. No comment is always better than an obsolete, redundant, misleading, or just plain wrong comment.
If the rest of this coding standard is observed, you will rarely find it necessary to add comments. To put it another way, code that meets the standard of customer readability does not require a lot of comments. Please read the code in the example application to get the feel of what is meant by customer-readable code.
The remainder of this section of the standard spells out both the kinds of comments that should be avoided, and it identifies a couple of those rare circumstances where a comment is a good idea.
Comments not only take time and energy to create, they take even more resources if they are kept up-to-date enough to be useful. Most commonly, comments are not kept up. Neither the compiler nor run-time alerts give any notice that a comment is no longer accurate. Over time, the comments become less and less reliable and, in many cases, misleading.
Often comments are used to describe what a section of code does. Use this as an alert to identify a potential subroutine. It eliminates the need to maintain a comment and maximizes the potential for reuse.
The time and energy spent writing comments are better spent on making the code readable enough to render the comments superfluous. Put the compiler on your side. For example, if you change the name of a subroutine to make it more descriptive and readable, the compiler will force you to change the name wherever the subroutine is called. Don't just search and replace. Take a few seconds to read the name, and make certain that name makes sense in each context.
Do not include header comments of any type. It is the responsibility of the configuration management tool to track all of the information that programmers have traditionally put into header comments: the creator of routine, the person responsible for each change, the purpose of each change, and the time and date of each change.
Do not include header comments that explain the purpose of the routine or module. If the purpose and use of a routine or module is not explicitly clear from the name of the entity, change the name of the entity.
Not only does this remove clutter from modules and subroutines, the job is easier to do with a good tool like Visual SourceSafe or PVCS and the information ends up where it's needed when it's needed.
All associates must own and use the client version of Visual SourceSafe (Included in the Enterprise edition of Visual Basic and Visual C++)
If you need comments to explain "What " the code is doing, you need to re-write your code. The presence of this kind of comment almost always indicates insufficient modularity and decomposition.
Exceptions to this rule will be few and far between. If you see a section of code that is not immediately understandable, break it out into a subroutine whose name identifies the what, and if possible, the why for that collection of code. Even if no further conscious thought is given to that subroutine, you often be surprised you will reuse a section of code that you considered trivial. Please see routines like Add_to_List in message.bas that demonstrate a trivial routine that has been reused literally thousands of times.
Don't clutter up your code with lines of asterisks or similar symbols. If a part of a subroutine is so significant that it requires this level of attention, that part almost certainly belongs in a separate subroutine.
If you can apply sufficient artistry to the creation of your code, it will explain why it does what it does as well as what it does. Unfortunately, this is not always a reachable goal.
In those cases, you need to rely first on your configuration management tool. That should be the repository of all design decisions, and often that record alone will be sufficient.
Other times, you need a comment. For example, you usually would refresh a data control after changing the record source for a data control. Not only should you not do this when you use a parameter query, doing so generates a missing parameter error. A comment to this effect may save someone (probably you) from inserting the refresh statement as a reflex.
It is acceptable (recommended even) to layout the design for subroutines using pseudo-code. The pseudo-code should be written so that it can smoothly transition to compilable statements as soon as stubs have been created for the necessary subroutines. These comments should have completed that transition by delivery of the first working prototype.
For example:
'if This_Record_was_Found() then
' Edit_This_Record
'else
' Add_New_Record
'end if
Private Function This_Record_was_Found() As Boolean
Private Sub Edit_This_Record
Private Sub Add_New_Record
The main point here is that creating the stubs and removing the leading quotes from the pseudo-code results in a readable, understandable, high level routine. As a fringe benefit, functionally cohesive subroutines are defined at their proper level of abstraction. (Of course parameters are almost certainly going to be needed for these routines, but that's a "down the road" consideration.)
You don't need to be Shakespeare to write readable code. Start with pseudo-code that explains the customer's requirements in the customer's language, and get the customer to confirm that you have done this correctly. Until you have done this simple verification, any work invested in lower-level implementation and design details is likely to be wasted.