13.2.4 Строки документации функций

Лямбда-выражение может иметь необязательную строку документации сразу после списка лямбда. Эта строка не влияет на выполнение функции; это своего рода комментарий, но систематизированный комментарий, который фактически появляется в мире Lisp и может использоваться общими средствами справки Emacs. См. Документация, как получить доступ к строке документации.

Хорошей идеей является предоставление строк документации для всех функций в вашей программе, даже тех, которые вызываются только внутри вашей программы. Строки документации похожи на комментарии, за исключением того, что к ним легче получить доступ.

Первая строка строки документации должна стоять отдельно, потому что apropos отображает только эту первую строку. Она должна состоять из одного или двух полных предложений, обобщающих назначение функции.

Начало строки документации обычно отстужено в исходном файле, но поскольку эти пробелы стоят перед начальной двойной кавычкой, они не являются частью строки. Некоторые люди практикуют отступы для любых дополнительных строк строки, чтобы текст выравнивался в исходном коде программы. Это ошибка. Отступы последующих строк находятся внутри строки; то, что выглядит красиво в исходном коде, будет выглядеть некрасиво при отображении с помощью команд справки.

Строка документации всегда должна сопровождаться как минимум одним выражением Lisp; в противном случае это не строка документации, а одно выражение тела, используемое в качестве возвращаемого значения. Когда нет значимого значения для возврата из функции, стандартной практикой является возврат nil, добавив его после строки документации.

Последняя строка строки документации может указывать соглашения о вызове, отличные от фактических аргументов функции. Напишите текст так:

\(fn arglist)

следуя пустой строке, в начале строки, без перевода строки после нее внутри строки документации. (Символ ‘\’ используется для избежания путаницы с командами перемещения Emacs.) Соглашение о вызове, указанное таким образом, появляется в сообщениях справки вместо того, которое выводится из фактических аргументов функции.

Эта функция особенно полезна для определений макросов, поскольку аргументы, указанные в определении макроса, часто не соответствуют способу, которым пользователи представляют части вызова макроса.

Не используйте эту функцию, если вы хотите устареть соглашение о вызове и отдать предпочтение тому, которое вы рекламируете вышеуказанной спецификацией. Вместо этого используйте объявление advertised-calling-convention (см. Форма declare) или set-advertised-calling-convention (см. Объявление функций устаревшими), потому что эти два вызовут компилятор байт, выдав предупреждение, когда компилирует программы Lisp, использующие устаревшее соглашение о вызове.

Функция (fn) обычно используется в следующих ситуациях:

Строки документации обычно статичны, но иногда может потребоваться генерировать их динамически. В некоторых случаях вы можете сделать это, написав макрос, который генерирует во время компиляции код функции, включая желаемую строку документации. Но вы также можете сгенерировать строку документации динамически, написав (:documentation form) вместо строки документации. Это вызовет вычисление form во время выполнения, когда функция определяется, и использует его в качестве строки документации13. Вы также можете вычислить строку документации на лету, когда она запрашивается, установив свойство function-documentation символа функции в форму Lisp, которая вычисляется в строку.

Например:

(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"

Примечания

(13)

Это работает только в коде с использованием lexical-binding.