Code Comments: How to Write Clean and Maintainable Code

Discover the benefits of good code comments and learn best practices for writing effective documentation. Improve code quality, readability, and collaboration. By Roberto Machorro.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Beyond Annotations

Up to this point, you’ve learned about using comments as annotations. However, since comments have no predefined format, you can extend their use by transforming your humble comment annotation into a data file or specialized document. Here are some good examples.

LICENSE Comments

LICENSE is a type of comment that indicates terms and conditions for the code. You’ll see these especially often in open-source code. Here’s an example from the MIT LICENSE:

/*
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

Since comments are free-form, the way the comment is typed can take many shapes. Here’s an example from Apple:

//===---------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2015-2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===---------------------------------------------------------------===//

TEMPORARY CODE-OUT Comments

Programmers use the TEMPORARY CODE-OUT comment as a tool for debugging. By taking a block or line of code out of the compile process, you can alter which code executes and which doesn’t. This method is commonly used when doing a process-of-elimination debug. For example (only building for iOS):

let package = Package(
  name: "CommentOut",
  platforms: [
    .iOS(.v14), /* .tvOS(.v14), .watchOS(.v7), .macOS(.v11) */
  ],
  products: [
    .library(name: "CommentOut", targets: ["CommentOut"])
  ],
  targets: [
    .target(name: "CommentOut")
  ]
)

DECORATIVE Comments

A DECORATIVE or SEPARATOR comment can separate a file or blocks of code by some category or function. This helps users find code more easily. Here’s an example:

/**************************************************
 * Huffman Implementation Helpers                 *
 **************************************************/

LOGIC Comments

LOGIC comments document the rationale you chose when creating the code. This goes beyond what the code shows, like “What was that value assigned?”

For example (from swift-package-manager/Sources/Commands/SwiftRunTool.swift, lines 287-288):

private func execute(path: String, args: [String]) throws -> Never {
  #if !os(Windows)
  // On platforms other than Windows, signal(SIGINT, SIG_IGN) is used for handling SIGINT by DispatchSourceSignal,
  // but this process is about to be replaced by exec, so SIG_IGN must be returned to default.
  signal(SIGINT, SIG_DFL)
  #endif

  try TSCBasic.exec(path: path, args: args)
}

In this case, the execute function contains compile conditional instructions that will either include or skip the signal call. The comment contains the explanation as to why it does this.

Advanced Forms of Comments

Comments can hold specialized content, typically formatted just like a data file would be: a file within the code. They can also be simple flags, which source code parser tools can respond to in different ways.

Flag Comments

Flag comments are typically used by linters; they enable or disable features. Here’s how SwiftLint disables features using flag comments:

struct GitHubUserInfo: Content {
  let name: String
  // swiftlint:disable identifier_name
  let avatar_url: String?
  // swiftlint:enable identifier_name
}

Compilers themselves also use flag comments as a form of setup. In the example below, you see a Python script run as a CLI script and in UTF-8 format:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
Note: The first comment line in scripts has a formal name: the shebang. Its purpose is to indicate which interpreter the operating system should use when it executes the script. It always starts with a #!.

TASK Comments

Integrated development environments (IDEs), text editors and some CLI tools are able to read TASK comments left by programmers in a format that indicates an action to be performed by the programmer in the future, such as TODO:

// TODO: Switch Model permissions

// FIXME: Convert strings to Enum

DOCUMENT GENERATION Comments

DOCUMENT GENERATION comments allow a tool to parse the source code and output a formatted document — typically HTML — that end users can use to browse classes, methods, etc. Here’s an example from JavaDoc:

/**
 * @param string  the string to be converted
 * @param type    the type to convert the string to
 * @param <T>     the type of the element
 * @param <V>     the value of the element
 */
<T, V extends T> V convert(String string, Class<T> type) {
}

Other tools can generate documentation that’s seen by IDEs and shown to the user within the code. One such tool is Documentation Markup (DocC). This is particularly useful for APIs Apple uses with its own libraries. Here’s an example from the open-source SwiftGD project:

/// Exports the image as `Data` object in specified raster format.
///
/// - Parameter format: The raster format of the returning image data (e.g. as jpg, png, ...). Defaults to `.png`
/// - Returns: The image data
/// - Throws: `Error` if the export of `self` in specified raster format failed.
public func export(as format: ExportableFormat = .png) throws -> Data {
  return try format.data(of: internalImage)
}

CDATA Comments

CDATA comments embed formatted data within XML and XHTML files. You can use several different types with these comments, such as images, code, XML within XML, etc.:

<![CDATA[<sender>John Smith</sender>]]>

From Wikipedia’s article on Computer Programming Comments, you have the RESOURCE inclusion type of comment: “Logos, diagrams, and flowcharts consisting of ASCII art constructions can be inserted into source code formatted as a comment”. For example:

<resource id="ProcessDiagram000">
<![CDATA[
 HostApp (Main_process)
    |
    V
script.wsf (app_cmd) --> ClientApp (async_run, batch_process)
                |
                |
                V
         mru.ini (mru_history)  
]]>
</resource>

Having Fun With Comments

Just because comments aren’t included with an app doesn’t mean you can’t have fun with them. Life lessons, jokes, poetry, tic-tac-toe games and some coworker banter have all made it into code comments. Here’s an example from py_easter_egg_zen.py:

import this

# The Zen of Python, by Tim Peters

# Beautiful is better than ugly.
# Explicit is better than implicit.
# Simple is better than complex.
# Complex is better than complicated.
# Flat is better than nested.
# Sparse is better than dense.
# Readability counts.
# Special cases aren't special enough to break the rules.
# Although practicality beats purity.
# Errors should never pass silently.
# Unless explicitly silenced.
# In the face of ambiguity, refuse the temptation to guess.
# There should be one-- and preferably only one --obvious way to do it.
# Although that way may not be obvious at first unless you're Dutch.
# Now is better than never.
# Although never is often better than *right* now.
# If the implementation is hard to explain, it's a bad idea.
# If the implementation is easy to explain, it may be a good idea.
Important: Easter egg comments aren’t welcome in all source codes. Please refer to the project or repository policy or your employee handbook before doing any of these.