Using Comments in Code (and DbC)

There is a lot of VBA code out there that is devoid of comments. Partly, this is due the lightweight development culture of VBA. You’re just ‘knocking something together quickly’, so you won’t bother with comments, maybe later. We’re all guilty of this to some extent (oh, sorry, you’re the one person who always comments rigorously…). So I think it helps to have a clear idea of what you use comments for.

First the negative cases (what not to use comments for):

  • The plonkingly obvious: paraphrases of code that should be clear enough on its own (i = i + 1     ‘increment counter)
  • Comments to describe sections of a procedure that is too long, and should be broken up into separate procedures.

Now the positive cases:

  • Module header comments: what a module is about; a list of its Public procedures (i.e. its interface)
  • Procedure pre-conditions and post-conditions: more on these below
  • On Dim statements, to expand on the local variable names (I tend to favour shortish names)
  • Working notes during development. e.g. “No error handling yet”, “No validation of user input”
  • Commenting out blocks of code (though these aren’t meaningful comments).

I think they are all fairly obvious, apart from the second one. This is based on the idea of Design by Contract (DbC), advocated by Bertrand Meyer, and implemented in the Eiffel language.

The idea of a pre-condition is that a procedure states what it assumes to be true at the time it is called. Often, the pre-condition will concern the procedure’s arguments. For example:

  • an integer is positive, or negative, or within a limit
  • a date is in the future, or the past, or within a period
  • a string is non-empty, or a certain length, or numeric
  • an object reference is valid (not ‘nothing’).

A header comment in the procedure is the place to state such pre-conditions. What this does is push the responsibility for ensuring the pre-conditions on to the caller(s) of the procedure. There is thus a clear division of labour between caller and called procedure.

For example, suppose an event-handler in a Form calls a support procedure in a general module, passing some user input (a product Id, say). For the support procedure to do its stuff, it requires that the user input is valid. Stating this in a pre-condition makes it clear that it’s the Form’s job to ensure this. In practice, the Form ensures that the input is valid, by some means: e.g. checking values in the OKbutton_click handler, or using a dropdown list populated with the set of valid values. A key point is that the pre-condition means that the called procedure does not need to check or validate the condition, which makes the code simpler.

The complement of a procedure’s pre-condition is its post-condition: what the procedure ensures is the case when it has finished execution. This is particularly useful for Functions, where the post-condition relates to the returned value. Again, it might be that the result is not zero/empty/nothing. The caller can then rely on this being the case, and does not need to check it, making its code simpler.

Here’s an example:

Function OrderPrice (productid As String, _
             quantity As Integer) As Currency
    'pre: productid is valid and product.unit_price > 0
    'pre: quantity > 0
    'post: OrderPrice > 0

    'clever stuff with discounts and delivery charges ...
End Function

Post-conditions can also refer to:

  • changes made to the document/workbook/etc, such as adding or deleting elements
  • the result of searches (what happens if the search fails? is there a default?)
  • files written to disk, or other external changes
  • and so on.

This might seem a bit of a performance, but it’s really just a mindset, in which you think about what procedures are supposed to be doing (that is, their specification), not just as arbitrary lumps of code. Ok, I think I’ll get off my hobby horse now…


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

February 2009
« Jan   Mar »

%d bloggers like this: