13.2.4 Documentation Strings of Functions

A lambda expression may optionally have a documentation string just after the lambda list. This string does not affect execution of the function; it is a kind of comment, but a systematized comment which actually appears inside the Lisp world and can be used by the Emacs help facilities. See Documentation, for how the documentation string is accessed.

It is a good idea to provide documentation strings for all the functions in your program, even those that are called only from within your program. Documentation strings are like comments, except that they are easier to access.

The first line of the documentation string should stand on its own, because apropos displays just this first line. It should consist of one or two complete sentences that summarize the function’s purpose.

The start of the documentation string is usually indented in the source file, but since these spaces come before the starting double-quote, they are not part of the string. Some people make a practice of indenting any additional lines of the string so that the text lines up in the program source. That is a mistake. The indentation of the following lines is inside the string; what looks nice in the source code will look ugly when displayed by the help commands.

You may wonder how the documentation string could be optional, since there are required components of the function that follow it (the body). Since evaluation of a string returns that string, without any side effects, it has no effect if it is not the last form in the body. Thus, in practice, there is no confusion between the first form of the body and the documentation string; if the only body form is a string then it serves both as the return value and as the documentation.

The last line of the documentation string can specify calling conventions different from the actual function arguments. Write text like this:

\(fn arglist)

following a blank line, at the beginning of the line, with no newline following it inside the documentation string. (The ‘\’ is used to avoid confusing the Emacs motion commands.) The calling convention specified in this way appears in help messages in place of the one derived from the actual arguments of the function.

This feature is particularly useful for macro definitions, since the arguments written in a macro definition often do not correspond to the way users think of the parts of the macro call.

Do not use this feature if you want to deprecate the calling convention and favor the one you advertise by the above specification. Instead, use the advertised-calling-convention declaration (see The declare Form) or set-advertised-calling-convention (see Declaring Functions Obsolete), because these two will cause the byte compiler emit a warning message when it compiles Lisp programs which use the deprecated calling convention.

The (fn) feature is typically used in the following situations:

Documentation strings are usually static, but occasionally it can be necessary to generate them dynamically. In some cases you can do so by writing a macro which generates at compile time the code of the function, including the desired documentation string. But you can also generate the docstring dynamically by writing (:documentation form) instead of the documentation string. This will evaluate form at run-time when the function is defined and use it as the documentation string12. You can also compute the documentation string on the fly when it is requested, by setting the function-documentation property of the function’s symbol to a Lisp form that evaluates to a string.

For example:

(defun adder (x)
  (lambda (y)
    (:documentation (format "Add %S to the argument Y." x))
    (+ x y)))
(defalias 'adder5 (adder 5))
(documentation 'adder5)
    ⇒ "Add 5 to the argument Y."

(put 'adder5 'function-documentation
     '(concat (documentation (symbol-function 'adder5) 'raw)
              "  Consulted at " (format-time-string "%H:%M:%S")))
(documentation 'adder5)
    ⇒ "Add 5 to the argument Y.  Consulted at 15:52:13"
(documentation 'adder5)
    ⇒ "Add 5 to the argument Y.  Consulted at 15:52:18"

Footnotes

(12)

This only works in code using lexical-binding.