From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Richard Stallman Newsgroups: gmane.emacs.devel Subject: Re: improvement in functions.texi Date: Sun, 05 Jan 2020 17:21:41 -0500 Message-ID: References: <87imlxlrrv.5.fsf@jidanni.org> <87mub85ri0.fsf@web.de> <87h81f3our.5.fsf@jidanni.org> <87v9pv28qu.fsf@web.de> <87d0c33mdx.5.fsf@jidanni.org> <87o8vnq1ph.fsf@web.de> <875zhv3jyr.5.fsf@jidanni.org> <87eewjydyg.fsf@web.de> <87sgkw60fi.5.fsf@jidanni.org> <8736cwrub9.5.fsf@jidanni.org> <87y2uoqds6.5.fsf@jidanni.org> Reply-To: rms@gnu.org Content-Type: text/plain; charset=Utf-8 Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="186568"; mail-complaints-to="usenet@blaine.gmane.org" Cc: michael_heerdegen@web.de, pieter-l@vanoostrum.org, jidanni@jidanni.org To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jan 05 23:22:42 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1ioEIC-000mN7-PQ for ged-emacs-devel@m.gmane.org; Sun, 05 Jan 2020 23:22:40 +0100 Original-Received: from localhost ([::1]:45738 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ioEIB-0008PL-KQ for ged-emacs-devel@m.gmane.org; Sun, 05 Jan 2020 17:22:39 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43208) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ioEHG-0007fw-Jh for emacs-devel@gnu.org; Sun, 05 Jan 2020 17:21:47 -0500 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:44459) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ioEHG-00084Q-FH; Sun, 05 Jan 2020 17:21:42 -0500 Original-Received: from rms by fencepost.gnu.org with local (Exim 4.82) (envelope-from ) id 1ioEHF-00012M-Fb; Sun, 05 Jan 2020 17:21:41 -0500 In-Reply-To: (message from Richard Stallman on Sat, 04 Jan 2020 18:48:59 -0500) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:244010 Archived-At: [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] I propose this improvement in functions.texi. The biggest change is moving the description of define-inline into the node Inline Functions where it semantically fits better. But this also adds a cross reference in Defining Functions to information about undefining. diff -u /home/rms/emacs-git/build-oct-2/doc/lispref/functions.texi.\~2\~ /home/rms/emacs-git/build-oct-2/doc/lispref/functions.texi --- /home/rms/emacs-git/build-oct-2/doc/lispref/functions.texi.~2~ 2019-10-26 08:57:05.985082189 -0400 +++ /home/rms/emacs-git/build-oct-2/doc/lispref/functions.texi 2020-01-05 16:12:09.453450858 -0500 @@ -575,8 +575,9 @@ @cindex defining a function We usually give a name to a function when it is first created. This -is called @dfn{defining a function}, and it is done with the -@code{defun} macro. +is called @dfn{defining a function}, and we usually do it with the +@code{defun} macro. This section also describes other ways to define +a function. @defmac defun name args [doc] [declare] [interactive] body@dots{} @code{defun} is the usual way to define new Lisp functions. It @@ -681,95 +682,8 @@ and tells the Lisp compiler to perform inline expansion on it. @xref{Inline Functions}. - Alternatively, you can define a function by providing the code which -will inline it as a compiler macro. The following macros make this -possible. - -@c FIXME: Can define-inline use the interactive spec? -@defmac define-inline name args [doc] [declare] body@dots{} -Define a function @var{name} by providing code that does its inlining, -as a compiler macro. The function will accept the argument list -@var{args} and will have the specified @var{body}. - -If present, @var{doc} should be the function's documentation string -(@pxref{Function Documentation}); @var{declare}, if present, should be -a @code{declare} form (@pxref{Declare Form}) specifying the function's -metadata. -@end defmac - -Functions defined via @code{define-inline} have several advantages -with respect to macros defined by @code{defsubst} or @code{defmacro}: - -@itemize @minus -@item -They can be passed to @code{mapcar} (@pxref{Mapping Functions}). - -@item -They are more efficient. - -@item -They can be used as @dfn{place forms} to store values -(@pxref{Generalized Variables}). - -@item -They behave in a more predictable way than @code{cl-defsubst} -(@pxref{Argument Lists,,, cl, Common Lisp Extensions for GNU Emacs -Lisp}). -@end itemize - -Like @code{defmacro}, a function inlined with @code{define-inline} -inherits the scoping rules, either dynamic or lexical, from the call -site. @xref{Variable Scoping}. - -The following macros should be used in the body of a function defined -by @code{define-inline}. - -@defmac inline-quote expression -Quote @var{expression} for @code{define-inline}. This is similar to -the backquote (@pxref{Backquote}), but quotes code and accepts only -@code{,}, not @code{,@@}. -@end defmac - -@defmac inline-letevals (bindings@dots{}) body@dots{} -This is similar to @code{let} (@pxref{Local Variables}): it sets up -local variables as specified by @var{bindings}, and then evaluates -@var{body} with those bindings in effect. Each element of -@var{bindings} should be either a symbol or a list of the form -@w{@code{(@var{var} @var{expr})}}; the result is to evaluate -@var{expr} and bind @var{var} to the result. The tail of -@var{bindings} can be either @code{nil} or a symbol which should hold -a list of arguments, in which case each argument is evaluated, and the -symbol is bound to the resulting list. -@end defmac - -@defmac inline-const-p expression -Return non-@code{nil} if the value of @var{expression} is already -known. -@end defmac - -@defmac inline-const-val expression -Return the value of @var{expression}. -@end defmac - -@defmac inline-error format &rest args -Signal an error, formatting @var{args} according to @var{format}. -@end defmac - -Here's an example of using @code{define-inline}: - -@lisp -(define-inline myaccessor (obj) - (inline-letevals (obj) - (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2))))) -@end lisp - -@noindent -This is equivalent to - -@lisp -(defsubst myaccessor (obj) - (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2))) -@end lisp + To undefine a function name, use @code{fmakunbound}. +@xref{Function Cells}. @node Calling Functions @section Calling Functions @@ -2154,8 +2068,12 @@ An @dfn{inline function} is a function that works just like an ordinary function, except for one thing: when you byte-compile a call to the function (@pxref{Byte Compilation}), the function's definition -is expanded into the caller. To define an inline function, use -@code{defsubst} instead of @code{defun}. +is expanded into the caller. + + The simple way to define an inline function, is to write +@code{defsubst} instead of @code{defun}. The rest of the definition +looks just the same, but using @code{defsubst} says to make it inline +for byte compilation. @defmac defsubst name args [doc] [declare] [interactive] body@dots{} This macro defines an inline function. Its syntax is exactly the same @@ -2193,9 +2111,95 @@ worry about how many times the body uses the arguments, as you do for macros. - As an alternative to @code{defsubst}, you can use -@code{define-inline} to define functions via their exhaustive compiler -macro. @xref{Defining Functions, define-inline}. + Alternatively, you can define a function by providing the code which +will inline it as a compiler macro. The following macros make this +possible. + +@c FIXME: Can define-inline use the interactive spec? +@defmac define-inline name args [doc] [declare] body@dots{} +Define a function @var{name} by providing code that does its inlining, +as a compiler macro. The function will accept the argument list +@var{args} and will have the specified @var{body}. + +If present, @var{doc} should be the function's documentation string +(@pxref{Function Documentation}); @var{declare}, if present, should be +a @code{declare} form (@pxref{Declare Form}) specifying the function's +metadata. +@end defmac + +Functions defined via @code{define-inline} have several advantages +with respect to macros defined by @code{defsubst} or @code{defmacro}: + +@itemize @minus +@item +They can be passed to @code{mapcar} (@pxref{Mapping Functions}). + +@item +They are more efficient. + +@item +They can be used as @dfn{place forms} to store values +(@pxref{Generalized Variables}). + +@item +They behave in a more predictable way than @code{cl-defsubst} +(@pxref{Argument Lists,,, cl, Common Lisp Extensions for GNU Emacs +Lisp}). +@end itemize + +Like @code{defmacro}, a function inlined with @code{define-inline} +inherits the scoping rules, either dynamic or lexical, from the call +site. @xref{Variable Scoping}. + +The following macros should be used in the body of a function defined +by @code{define-inline}. + +@defmac inline-quote expression +Quote @var{expression} for @code{define-inline}. This is similar to +the backquote (@pxref{Backquote}), but quotes code and accepts only +@code{,}, not @code{,@@}. +@end defmac + +@defmac inline-letevals (bindings@dots{}) body@dots{} +This is similar to @code{let} (@pxref{Local Variables}): it sets up +local variables as specified by @var{bindings}, and then evaluates +@var{body} with those bindings in effect. Each element of +@var{bindings} should be either a symbol or a list of the form +@w{@code{(@var{var} @var{expr})}}; the result is to evaluate +@var{expr} and bind @var{var} to the result. The tail of +@var{bindings} can be either @code{nil} or a symbol which should hold +a list of arguments, in which case each argument is evaluated, and the +symbol is bound to the resulting list. +@end defmac + +@defmac inline-const-p expression +Return non-@code{nil} if the value of @var{expression} is already +known. +@end defmac + +@defmac inline-const-val expression +Return the value of @var{expression}. +@end defmac + +@defmac inline-error format &rest args +Signal an error, formatting @var{args} according to @var{format}. +@end defmac + +Here's an example of using @code{define-inline}: + +@lisp +(define-inline myaccessor (obj) + (inline-letevals (obj) + (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2))))) +@end lisp + +@noindent +This is equivalent to + +@lisp +(defsubst myaccessor (obj) + (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2))) +@end lisp @node Declare Form @section The @code{declare} Form Diff finished. Sun Jan 5 16:20:31 2020 -- Dr Richard Stallman Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org)