/ IOS

The Art of Commenting in Swift

Comments are integral part of every project’s code base. Their quality is equally important as that of the code. Writing excellent comments is way easier than the code, and can be mastered by studying several best practices. Even if you’ve never written a single comment before, you can get off to a flying start in just a few minutes by reading this article.

Importance of Comments

According to Structure and Interpretation of Computer Programs:

Programs must be written for people to read, and only incidentally for machines to execute.

Regardless of how concise and clear your code is, it cannot be 100% self-documenting. What seems crystal clear to you at the time of writing, might be totally confusing to a reader. This means that code cannot completely replace comments.

Why one might refrain from commenting? The common reasons are:

  1. Hubris: “I can understand my code well, the rest is not my problem” or “Good code speaks for itself”.
  2. Laziness.
  3. Deadlines.

Each of the above is not really an excuse and is easily beaten by Robert C. Martin:

The time we spend reading the code is over 10x more than writing it.

Furthermore, Facts and Fallacies of Software Engineering has shown that 40%–80% of the total program cost goes to maintenance.

Hence, commenting done right actually saves time and contributes to your Swift app a lot.

Types of Comments

By their purpose, all comments can be abstracted into four groups:

  1. Documentary
  2. Functional
  3. Explanatory
  4. Stress relief

1. Documentary comments capture the history and development of the file. Their core purpose is to improve code maintainability. Most notable examples are:

  • Filename
  • Project name
  • Creation and modification dates
  • Author
  • Copyright
  • Version
  • History of changes
  • Dependencies

Documentary comments are wordy and error-prone if typed manually. Capture only those details, which are not available to version controls tools like git.

We are dealing with documentary comments every day, often without realizing it:

//
//  AppDelegate.swift
//  Article-SwiftComments
//
//  Created by Vadym Bulavin on 4/9/19.
//  Copyright © 2019 Vadym Bulavin. All rights reserved.
//

How many points from the list have you counted? Xcode adds 5 points to each new Swift file: file and project name, creation date, author and copyright. Are all of them valuable? I would answer yes only to the copyright, since the rest can be easily extracted from the git history.

2. Functional comments add features to development process. Swift has 4 groups of functional comments:

  • Diagnostic directives: #warning, #error.
  • Annotations: TODO, MARK, FIXME, 3rd-party-specific (swiftlint:disable, sourcery:begin:).
  • Bugfix notes: who fixed the bug, when and how. E.g. “Bugfix: This is how I fixed it. -VABU”.
  • Performance improvement notes.

When writing functional comments, stick to the same style and format. Otherwise, the tools won’t process them and the benefit will be lost. You do not want to miss an important TODO just because it is misspelled.

3. Explanatory comments summarize code or to explain the programmer’s intent.

Steve McConnell says:

Good comments don’t repeat the code or explain it. They clarify its intent.

In other words, comments must answer the question why instead of what.

Explanatory comments make the most sense in next scenarios:

  • Code does not fit project conventions
  • Algorithm description: name, complexity, documentation
  • Complex regular expressions
  • Workarounds

4. Stress relief comments refer to code quality, development tools, are attempts to joke. They often contain offensive language. I suggest to refrain from them.

Comment Syntax

Swift comments can be written in two formats:

  • Each line is preceded by a triple slash (///)
  • Javadoc-style block comments (/** … */)

The former format is preferred: it is used in standard libraries and can be generated in Xcode with hotkey Option (⌥) + Command (⌘) + Slash (/):

/// <#Description#>
///
/// - Parameter value: <#value description#>
/// - Returns: <#return value description#>
func isOdd(_ value: Int) -> Bool {
    return abs(value) % 2 == 1
}

Comment Content

Next important questions are what to comment and how. Let’s answer those with 10 rules of thumb.

1. Start a comment with a brief summary that describes the declaration. If needed, state more details in additional paragraphs after the summary:

/// Returns a random value within the specified range.
///
/// Use this method to generate an integer within a specific range. [...]
func random(in range: ClosedRange<Int>) -> Int

2. Do not repeat the subject of the comment, because it is already implied. Such phrases as “this property is …” are usually redundant.

/// [This property is] the text color of the label.
var textColor: UIColor

3. Terminate comment lines with a period.

4. Explain what a function does, instead of how it works:

extension Array {
  /// Adds a new element at the end of the array. [...]
  mutating func append(_ newElement: Element)
}

5. Explain what initializer creates:

extension Array {
  /// Creates a new, empty array. [...]
  init()
}

6. Explain what the entity is:

/// A view that displays one or more lines of read-only text. [...]
class UILabel: UIView {
    ...
}

7. Refrain from comments that simply re-state the information, which is obvious from the declaration:

/// UITableViewDelegate conformance
extension ViewController: UITableViewDelegate {
  ...
}

The declaration is self-explanatory and the comment is meaningless.

8. Use Apple’s markup syntax to add rich formatting to documentation. It supports full CommonMark spec, extended with 25 Swift-specific terms.

9. When brief summary is not enough, continue the comment with a body. Format the body into paragraphs and bulleted lists, e.g. parameters, return values, notes, code blocks. Split the sections with a blank line:

extension Array {
  /// Adds a new element at the end of the array.
  ///
  /// Use this method to append a single element to the end of a mutable array.
  ///
  ///     var numbers = [1, 2, 3, 4, 5]
  ///     numbers.append(100)
  ///     print(numbers)
  ///     // Prints "[1, 2, 3, 4, 5, 100]"
  ///
  /// [...]
  ///
  /// - Parameter newElement: The element to append to the array.
  ///
  /// - Complexity: O(1) on average, over many calls to `append(_:)` on the
  ///   same array.
  mutating func append(_ newElement: Element)
}

When opened in Xcode QuickHelp, such comment looks well-structured and descriptive:

How to Comment Your Swift Code - Xcode QuickHelp

10. Document API changes with @available keyword.

@available(*, deprecated, renamed: "newMethodName")
func foo() {
  ...
}

Each time foo() is called, a deprecation warning will appear:

How to Comment Your Swift Code - Available Keyword

Summary

Code can only tell you how the program works; comments can tell you why it works. Remember that you write your code to be consumed by other programmers first, hence understanding the principles of writing high quality comments contributes to project quality a lot.

Other references that make great addition to the subject:


Thanks for reading!

If you enjoyed this post, be sure to follow me on Twitter to keep up with the new content. There I write daily on iOS development, programming, and Swift.

Vadim Bulavin

Creator of Yet Another Swift Blog. Coding for fun since 2008, for food since 2012.

Follow