Crafting Clearer Code: Write abundant, quality comments!

Squirrel wants to see your comments.

From the very start of your software-engineering you should compose cogent comments right along with your code. The only exception is where your code is so small that it is trivial and obvious (to anyone besides yourself) or else you are the only audience.

This is one of those areas in which, largely, older engineers make better code-crafters: they know that the universe of possible code-contructs, patterns, APIs, add-ons and libraries is truly vast. To assume it’ll all be obvious past this moment is to guarantee future frustration and time-wastage.

For your long-view guidance – to tell your teammates what your code does and it’s basic organization – provide a “Doc” folder and give it simple text, markdown or HTML documents. This should form your basic roadmap, and here you direct your reader where to go within the code. Everything that is missing from the code-level comments, should be here. If you’re going to structure this formally – then I’d suggest you also provide a separate, informal ‘quick roadmap’ or synopsis. Come back to this regularly: do not let it become too out-of-sync with your code such that it decays into uselessness.

Here I’ll direct my tips toward the crafting of code using C#..

Use the standard for code-contructs that Microsoft’s Visual Studio provides, which is:

/// <summary>
/// This integer tracks the number of insertions since the start of this current run.
/// It can range from zero, up.
/// </summary>
private int _insertionCount;

 

Within Visual Studio, all you need do is type the first three slashes and it produces the remaining slashes for you.

The advantage of this is that when you encounter this variable from anywhere else within your codebase, you need but hover your mouse over it and this comment will magically appear. It’s like having a crib-note always attached to it, but which hides itself until you need it. This is important – otherwise your readers must navigate to the code-element itself to see your comment.

Be useful. Here is a counter-example, taken from the iText product API documentation page:

// EOFills current path.
eoFill();
 

Yeah – that’s actually the kind of API-documentation that iText provides. Does that look useful to you?

Imagine you are *trying* very hard to use this API correctly and get your code to generate that Acrobat report correctly. The company depends on you and you’re at the 11th hour (true story). You’ve no clue nor hint what the heck EOFills means.  Does that make you want to slap a body?

Do NOT use domain-specific jargon in your comments. I’ve been using the iText 7 API to create Acrobat documents and I still have no idea what the hell that method is for. If you add a comment that simply repeats the text that is already within the method-name, you mark yourself as a total idiot who should never be permitted anywhere near a keyboard. Here is an example, in C#, from the  LogNut logging library  ..

/// <summary>
/// Set the name of the log file to write file logging output to.
/// If you don't set this then a default value will be computed. See <see cref="FileOutputFilename"/>.
/// This is the same as setting the <see cref="FileOutputFilename"/> property.
/// </summary>
/// <param name="filename">the name of the file to log to - without the drive or directory information</param>
/// <remarks>
/// If you set this to null, then upon re-reading this property the default value will again be returned.
/// This duplicates the function of the <see cref="FileOutputFilename"/> property setter, for the purpose of providing a fluent API.
/// </remarks>
/// <returns>a reference to this <c>LogConfig</c> object, such that further method calls may be chained</returns>
public LogConfig SetFileOutputFilenamestring filename )
{
    FileOutputFilename = filename;
    return this;
}
#endregion
 

Yeah – this is rather verbose. That’s okay – it takes two minutes to type, as opposed to untold minutes wasted by N developers trying to guess what the heck you mean when you *don’t* bother to explain. Note that it is made explicit what argument you should supply for filename – not a path, not a drive – just a filename. It’s also made quite explicit what this is for: the log output file. LogNut has many kinds of outputs – this is for *file* output. The sentences are complete, clear, unambiguous.

Make your writing readable. That sounds too obvious – but it’s a badly-needed admonishment. Your comments should read like good exposition: avoid too-esoteric terms when a generally-known word will serve, make your sentences read easily, without being wordy. Write to guide and inform, not to fill space and not to slow your reader down.

Use proper spelling and grammar. I try to encourage being rather strict in this for one reason: the human visual-system is such that we more readily recognize and digest writing when it it correctly formed (from the perspective of our own personal background). When your mind has to stop and guess at what “snd to pip recever” is intended to convey — that interrupts your flow of thought. The result is that it is harder, and slower, to read. For individual method-parameters, you can use a non-sentence phrase: “the number of items in the collection” but for anything longer you should assemble your writing into complete sentences. Start a fragment with a lowercase letter, and start a complete sentence with an uppercase letter. Invest a little time to make it explicit.

Regarding spelling: use a spell-checking tool in your code-editor. Why is correct spelling so important? For doing text-searches, for one. But also for your teammates for whom your language is not *their* native language. It’s hard enough to keep googling for translations, but can you imagine the difficulty when your own English is not even spelled correctly? Regardless of how careful you are – mispellings will creep in. A good spell-checker will highlight those for you. But bear in mind that British spelling diverges from American English in a few cases.

Decide upon your naming-scheme and structure, and make that a consistent pattern for you and your team. This is as important within your comments as it is within your code. For the things in your code that represent something in real life and can be named any of a number of different ways – consider how you want to name them, and stick to your scheme. These patterns help everyone’s mind to instantly follow it’s structure. For example, if you’re designing a desktop application that has views and view-models, why not name all views with a “View”suffice, and all view-models with a “ViewModel” suffice? Now make every comment, everywhere, use this same nomenclature. Placing the parent-class name after the class-name can be a helpful pattern: “PictureAcquiredEventArgs” is obviously a subclass of EventArgs. And on the topic of events..

A C# event is a signal that something happened. Name it with a verb-phrase in the past tense. The name should say that a thing happened, and the Intellisense-comment should give it further detail. If your event is named “ImageUploaded”, why not name the event arguments ImageUploadedEventArgs, and the event-handler method OnImageUploaded.. this pattern makes their relationship intuitively obvious. But don’t stop there: still add your comments. What does this class contain? What does this event-handler *do* in response to the event?

Now – this is the most illusive feature to maintain and yet is the most crucial: Make your comments such that, taken as a whole, they describe the operation of your system completely. *Completely*. You should be able to bring in a brand-new employee set them loose upon it – and see them begin to feel at ease going through your code and quickly start doing useful work. The larger constructs (assemblies, libraries, classes) should convey the overall purpose and organization of your code, while the individual code-constructs provide the detail *when* your reader feels the need to zoom-in for that level of detail.

Write a comment for every non-local construct in your code. All of them. And take some care to write your comments correctly and make them useful. And then re-visit your comments over the next days to rewrite them to maintain clarity and consistency.

 

James W. Hurst

return to On Building Systems