Subject: [PATCH] Add use cases of (fn) documentation facility.
From: Jeremy Bryant <[email-masked]>
To: [email-masked]
Date: Mon, 27 Nov 2023 23:30:33 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

I have written a proposed addition to the Elisp manual.  In now-closed
bug 66928, there was a discussion related to the use of \(fn) in doc
strings, and I have drafted some examples to explain how this facility
could be used.  The addition is presented as @ifnottex... in order to
reduce the cost of the printed manual.

Feedback welcome on draft before I refine further, on conventions, section of
manual, style etc.

> Interesting, thank you 
> Perhaps it would be of interest to add some text to the elisp manual in
> (elisp) Function Documentation

> Are there any conventions for manual additions?
> in particular to keep the number of printed pages limited is there a way
> to say 'don't print this node'?

> thanks
> Jeremy

> Stefan Monnier <[email-masked]> writes:

> >> One question, the elisp manual mentions that the \(fn ARGLIST) facility
> >> is particularly useful for macros.
> >>
> >> Why would we use this for defuns?
> >
> > We use it for some defuns where ELisp's arglist functionality is not
> > refined enough to express the intention of the programmer.
> > For example, the "real" arglist may be
> >
> >     name args &optional docstring &rest body
> >
> > but the intended arglist is
> >
> >     name args [docstring] &rest body
> >
> > i.e. if `docstring` is not a string it's taken as the first instruction
> > of `body`.
> >
> >
> >         Stefan

From 34d0e7b4a6f15769d7b32dc16e3f283f947069ab Mon Sep 17 00:00:00 2001
From: Jeremy Bryant <[email-masked]>
Date: Mon, 27 Nov 2023 23:18:03 +0000
Subject: [PATCH] Add use cases of (fn) documentation facility.

* doc/lispref/functions.texi (Function Documentation):  Add examples
---
 doc/lispref/functions.texi | 93 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index e646e7c8b0a..92972d070ee 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -533,6 +533,99 @@ Function Documentation
 compiler emit a warning message when it compiles Lisp programs which
 use the deprecated calling convention.
 
+
+@c We use it for some defuns where ELisp's arglist functionality is not
+@c refined enough to express the intention of the programmer.
+@c For example, the "real" arglist may be
+
+@c     name args &optional docstring &rest body
+
+@c but the intended arglist is
+
+@c     name args [docstring] &rest body
+
+@c i.e. if `docstring` is not a string it's taken as the first instruction
+@c of `body`.
+
+@ifnottex
+In this section we outline examples of the use of the (fn) facility.
+
+Example with defmacro:
+Here is a canonical example where arguments are unclear.
+In subr.el, the definition of lambda is as below, and the (fn) facility
+helps to spell out the arglist &rest.
+@example
+(defmacro lambda (&rest cdr)
+  "Return an anonymous function.
+\(fn ARGS [DOCSTRING] [INTERACTIVE] BODY)"
+  )
+@end example
+
+Similar example with defun:
+define-keymap in keymap.el
+The &rest definitions list is not clear, so the fn facility explains it.
+@example
+(defun define-keymap (&rest definitions)
+  "Create a new keymap and define KEY/DEFINITION pairs as key bindings.
+Return the new keymap.
+...
+\(fn &key FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)"
+@end example
+
+
+Example with defmacro of a required argument which gets renamed:
+In macroexp.el, the macro @code{macroexp--accumulate}, has a first
+argument of @code{var+list}, which is more clearly described to the
+user as @code{(var list)}.  Thus the arguments are clarified.
+See example below:
+@example
+(defmacro macroexp--accumulate (var+list &rest body)
+  "Return a list of the results of evaluating BODY for each element of LIST.
+Evaluate BODY with VAR bound to each `car' from LIST, in turn.
+Return a list of the values of the final form in BODY.
+The list structure of the result will share as much with LIST as
+possible (for instance, when BODY just returns VAR unchanged, the
+result will be eq to LIST).
+
+\(fn (VAR LIST) BODY...)"
+  (declare (indent 1))
+  (let ((var (car var+list))
+	(list (cadr var+list))
+...)))
+@end example
+
+Example with defalias:
+Example of abbrev-get in abbrev.el:
+In this example, the general get facility to get the value of a
+symbol's property, is better described as getting the relevant
+abbrev's property value.
+@example
+(defalias 'abbrev-get 'get
+  "Get the property PROP of abbrev ABBREV
+See `define-abbrev' for the effect of some special properties.
+
+\(fn ABBREV PROP)")
+@end example
+
+Similar example of cl--defalias in cl-lib.el:
+In this example, the arguments are the same, but for list they are called
+OBJECTS, and for cl-values they are called VALUES.
+
+@example
+(cl--defalias 'cl-values #'list
+  "Return multiple values, Common Lisp style.
+The arguments of `cl-values' are the values
+that the containing function should return.
+
+\(fn &rest VALUES)")
+@end example
+
+
+% See (elisp) Autoload for a mention of \fn to reference.
+
+@end ifnottex
+
+
 @cindex computed documentation string
 @kindex :documentation
 Documentation strings are usually static, but occasionally it can be
-- 
2.42.0