Comments and Docstrings

Overview

Questions Objectives Key Concepts / Tools
What are comments? Understand how to annotate code for clarity and collaboration. Inline comments (#), code readability
When should I use comments? Learn when comments add value and when they are unnecessary. “Why” vs “How” comments, avoiding redundant comments
What are docstrings? Learn how to document functions, classes, and modules for users. Docstrings ("""..."""), structured documentation
How do comments differ from docstrings? Distinguish between explanations for developers and documentation for users. Purpose, placement, and scope
How can I generate documentation from code? Use tools that turn docstrings into formatted help pages or manuals. Sphinx (Python), roxygen2 (R), docstring package
What makes good documentation? Write concise, up-to-date, and purpose-driven explanations. Consistency, clarity, relevance

Writing Effective Comments and Docstrings

Good code is not just about logic — it’s about communication.
Your future self and your collaborators will thank you for leaving clear explanations in the form of comments and docstrings.

Comments

Comments are short notes written directly in your source code.
They explain what’s happening, why it’s done a certain way, or clarify tricky sections.

Good comments

  • Explain why the code exists, not just what it does.
  • Clarify complex logic or unexpected decisions.
  • Are short, relevant, and kept up to date.

Bad comments

  • Repeat what the code already says.
  • Describe how the code works in plain English.
  • Leave dead (“zombie”) or outdated code commented out.
  • Replace version control (e.g., # changed 2020-07-03).

Example

# GOOD: explains reasoning
# Cap number of retries to prevent infinite loops on network failures
max_retries = min(requested_retries, 5)

# BAD: restates code
# Add 5 to x
x = x + 5

Write comments for people, not for the computer.

Docstrings

While comments explain pieces of code, docstrings describe functions, classes, and modules.

A docstring is a special formatted comment placed immediately after the function definition. Docstrings may be used to explain what a function does, how to use it, what input it requires, and what output it returns. Sometimes they also provide examples of usage. Since they are part of the code, people looking at the code will be able to read what the function does, however, tools exist to generate help and documentation pages from docstrings. Which means this information is automatically available through help(), IDE tooltips, and documentation generators like Sphinx.

Docstrings in Python

def multiply(x, y):
    """
    Multiply two numbers.

    Parameters
    ----------
    x : int or float
        The first value.
    y : int or float
        The second value.

    Returns
    -------
    int or float
        The product of x and y.
    """
    return x * y

You can view this documentation in Python with:

help(multiply)

Docstrings in R

Just like in Python, you can attach documentation directly to functions in R.
However, R does not natively support docstrings — instead, you use packages that interpret special comments and generate documentation automatically.

There are two main approaches:

  1. The docstring Package (for inline documentation)

If you want a simple way to add docstrings directly inside your script (without creating an R package), you can use the docstring package.

#### Example

library(docstring)

multiply <- function(x, y) {
#' @title Multiply two numbers
#' @description This function takes two input numbers and multiplies them.
#' It returns the multiplied result.
#' @param x The first number
#' @param y The second number
#' @return The product of x and y

 return(x * y)
}

# You can then view the documentation interactively:
?multiply
  1. The roxygen2 Package (for R Packages)

For R packages, the most common and powerful way to use docstrings is through roxygen2. It reads structured comments (starting with #’) and automatically generates help files in the man/ directory of your package.

#### Example

#' Multiply two numbers
#'
#' This function takes two input numbers and multiplies them together.
#'
#' @param x The first number.
#' @param y The second number.
#'
#' @return The product of \code{x} and \code{y}.
#' @examples
#' multiply(2, 3)
#' multiply(5, 0.5)
#'
#' @export
multiply <- function(x, y) {
  x * y
}

When you run:

roxygen2::roxygenise()

Roxygen2 automatically generates a help file (man/multiply.Rd) that can be accessed using:

?multiply

Why docstrings matter

  • They turn your code into self-documenting software.
  • Tools like Sphinx, pdoc, or Doxygen can build HTML or PDF docs automatically.
  • They help IDEs show contextual help as you type.
  • They make functions easier to reuse and test.

Best Practices Summary

Type Used for Style Example
Comment Explaining why or clarifying complex logic # single line # Prevent division by zero
Docstring Documenting functions, classes, or modules """ triple quotes """ See multiply() example above

Tips

Write comments as if you’re explaining the code to a new team member.

Keep comments close to the code they explain.

Update docstrings whenever the function changes.

Use consistent formatting.

Writing docstrings can be tedious, however coding assistants are great for these types of tedious and repetitive tasks.

Key Takeaway

Code tells you how something works. Comments help to explain sections that are not clear from the code itself. Docstrings tell what functions, classes, and modules do and how to use them.

Writing both makes your code understandable, maintainable, and reproducible — the foundation of good scientific and collaborative software.

Presenter slides

References