Document 'define-inline'
* doc/lispref/functions.texi (Defining Functions): Document 'define-inline' and related macros. * lisp/emacs-lisp/inline.el (inline-letevals): Doc fix.
This commit is contained in:
parent
6e79b6379f
commit
e48f6dd3f7
3 changed files with 107 additions and 11 deletions
|
@ -623,6 +623,96 @@ definition will have no effect on them.
|
||||||
and tells the Lisp compiler to perform inline expansion on it.
|
and tells the Lisp compiler to perform inline expansion on it.
|
||||||
@xref{Inline Functions}.
|
@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 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 Calling Functions
|
@node Calling Functions
|
||||||
@section Calling Functions
|
@section Calling Functions
|
||||||
@cindex function invocation
|
@cindex function invocation
|
||||||
|
@ -1706,19 +1796,24 @@ features of Emacs, you should not make a function inline, even if it's
|
||||||
small, unless its speed is really crucial, and you've timed the code
|
small, unless its speed is really crucial, and you've timed the code
|
||||||
to verify that using @code{defun} actually has performance problems.
|
to verify that using @code{defun} actually has performance problems.
|
||||||
|
|
||||||
It's possible to define a macro to expand into the same code that an
|
|
||||||
inline function would execute (@pxref{Macros}). But the macro would
|
|
||||||
be limited to direct use in expressions---a macro cannot be called
|
|
||||||
with @code{apply}, @code{mapcar} and so on. Also, it takes some work
|
|
||||||
to convert an ordinary function into a macro. To convert it into an
|
|
||||||
inline function is easy; just replace @code{defun} with
|
|
||||||
@code{defsubst}. Since each argument of an inline function is
|
|
||||||
evaluated exactly once, you needn't worry about how many times the
|
|
||||||
body uses the arguments, as you do for macros.
|
|
||||||
|
|
||||||
After an inline function is defined, its inline expansion can be
|
After an inline function is defined, its inline expansion can be
|
||||||
performed later on in the same file, just like macros.
|
performed later on in the same file, just like macros.
|
||||||
|
|
||||||
|
It's possible to use @code{defsubst} to define a macro to expand
|
||||||
|
into the same code that an inline function would execute
|
||||||
|
(@pxref{Macros}). But the macro would be limited to direct use in
|
||||||
|
expressions---a macro cannot be called with @code{apply},
|
||||||
|
@code{mapcar} and so on. Also, it takes some work to convert an
|
||||||
|
ordinary function into a macro. To convert it into an inline function
|
||||||
|
is easy; just replace @code{defun} with @code{defsubst}. Since each
|
||||||
|
argument of an inline function is evaluated exactly once, you needn't
|
||||||
|
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}.
|
||||||
|
|
||||||
@node Declare Form
|
@node Declare Form
|
||||||
@section The @code{declare} Form
|
@section The @code{declare} Form
|
||||||
@findex declare
|
@findex declare
|
||||||
|
|
1
etc/NEWS
1
etc/NEWS
|
@ -1425,6 +1425,7 @@ details.
|
||||||
It should be placed right where the docstring would be, and FORM is then
|
It should be placed right where the docstring would be, and FORM is then
|
||||||
evaluated (and should return a string) when the closure is built.
|
evaluated (and should return a string) when the closure is built.
|
||||||
|
|
||||||
|
+++
|
||||||
** define-inline provides a new way to define inlinable functions.
|
** define-inline provides a new way to define inlinable functions.
|
||||||
|
|
||||||
** New function `macroexpand-1' to perform a single step of macroexpansion.
|
** New function `macroexpand-1' to perform a single step of macroexpansion.
|
||||||
|
|
|
@ -102,7 +102,7 @@ VARS should be a list of elements of the form (VAR EXP) or just VAR, in case
|
||||||
EXP is equal to VAR. The result is to evaluate EXP and bind the result to VAR.
|
EXP is equal to VAR. The result is to evaluate EXP and bind the result to VAR.
|
||||||
|
|
||||||
The tail of VARS can be either nil or a symbol VAR which should hold a list
|
The tail of VARS can be either nil or a symbol VAR which should hold a list
|
||||||
of arguments,in which case each argument is evaluated and the resulting
|
of arguments, in which case each argument is evaluated and the resulting
|
||||||
new list is re-bound to VAR.
|
new list is re-bound to VAR.
|
||||||
|
|
||||||
After VARS is handled, BODY is evaluated in the new environment."
|
After VARS is handled, BODY is evaluated in the new environment."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue