dark mode light mode Search Menu
Search

docstrings

Adam Ferrari on Flickr

If you recall the Code Snippets article from the last issue, programming languages include the ability to add comments to code. Usually comments explain the purpose of a block or line of code to aid future maintenance. In early drafts of code, comments also can be used to hide versions of code used to test code or try different solutions to a problem.

There is a second, more rare, type of comments called docstrings. Unlike comments in code, which are stripped out when the code is compiled or run, docstrings remain embedded in the code. These docstrings provide help documentation as well as meta data. In some cases, docstrings can include formatting instructions, for example, to bold text or set heading level.

The most common use of docstrings appears to be providing help and useful meta data. For example, docstrings could be extracted to create a map of the code structure or identify code blocks assigned to a test suite. In Python, docstrings also can be used to provide help text from the command line to someone using a script, for example, to provide the syntax of the command and definitions of its switches.

While useful, docstrings appear only a few languages: Python, Elixir, Clojure, and Lisp. Lua and other languages have docstring-like functionality.

Here are a few examples to show how docstrings are coded.

Python

Python implemented docstrings in PEP 257 and PEP 258, in 2001, a year or two after the language began development. docstrings appear first in all Python modules, functions, classes, or methods. They are collected in a __doc__ object for that object. The first line of a docstring in Python is called an attribute docstring while any docstrings appearing after the initial attribute docstring are called additional docstrings.

The language uses triple double quotes around text to identify docstrings:

def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root: return _kos_root
    ...

Note the use of a period at the end of the docstring. Also, docstrings are active not descriptive, “Do this” or “Return that” instead of describing what happens, “Returns the pathname.” It's a subtle but important distinction.

Multiple line docstrings in Python include the initial one line summary docstring followed by a blank line and a more detailed description. Here is an example:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Of course, there are more subtleties about docstrings and Python. Read PEP 257 and PEP 258 for specific details about Python use of docstrings.

Elixir

The way Elixir uses docstrings is interesting. Here's an example:

defmodule MyModule do
  @moduledoc """
  Documentation for my module. With **formatting**.
  """
 
  @doc "Hello"
  def world do
    "World"
  end
end

In this example, note the triple double quotes around the docstring. This is the same syntax as docstrings in Python. However, note the **formatting** bit of the docstring. The double stars are Markdown syntax; when processed, the double stars will convert text to bold. The first instance of ** tells Markdown to wake up and start bold while the second instance of ** tells Markdown where to stop bold.

Clojure

Some docstrings in Clojure begin with a double semi-colon. Multi-line definitions also use the double semi-colon for each additional line.

;; Give function another name
user=> (def sys-map map)

In addition, a double-quote around a line of text, or multiple lines of text, and contained within parentheses also works as docstrings. Within the double-quotes, it's possible to use parentheses and even Markdown language, although Markdown support depends on what software is used to output the docstrings. Worst case, Markdown tags will simply be ignored and displayed as plain text.

(defn flatten
   "Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence.
   (flatten nil) returns an empty sequence"
   {:added "1.2"
    :static true}
   [x]
   (filter (complement sequential?)
           (rest (tree-seq sequentia? seq x))))l

Learn More

docstrings

https://en.wikipedia.org/wiki/Docstring

docstrings in Python

http://www.python.org/dev/peps/pep-0257/
http://www.python.org/dev/peps/pep-0258/
https://en.wikipedia.org/wiki/Doctest
http://docs.python.org/2/library/doctest.html
https://groups.google.com/forum/#!msg/comp.lang.python/DfzH5Nrt05E/Yyd3s7fPVxwJ
https://en.wikipedia.org/wiki/Pydoc
https://en.wikipedia.org/wiki/Sphinx_%28documentation_generator%29
http://sphinx-doc.org/

Elixir

http://elixir-lang.org/

Clojure

http://clojure.org/

Markdown Syntax

https://en.wikipedia.org/wiki/Markdown
http://daringfireball.net/projects/markdown/syntax

Documentation Generators

https://en.wikipedia.org/wiki/Comparison_of_documentation_generators
https://en.wikipedia.org/wiki/Epydoc
http://epydoc.sourceforge.net/

Documentation from docstrings in Multiple Languages

http://www.stack.nl/~dimitri/doxygen/