An 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 (see Byte Compilation), the function’s definition is expanded into the caller.
The simple way to define an inline function, is to write
defsubst instead of
defun. The rest of the definition
looks just the same, but using
defsubst says to make it inline
for byte compilation.
This macro defines an inline function. Its syntax is exactly the same
defun (see Defining Functions).
Making a function inline often makes its function calls run faster. But it also has disadvantages. For one thing, it reduces flexibility; if you change the definition of the function, calls already inlined still use the old definition until you recompile them.
Another disadvantage is that making a large function inline can increase the size of compiled code both in files and in memory. Since the speed advantage of inline functions is greatest for small functions, you generally should not make large functions inline.
Also, inline functions do not behave well with respect to debugging,
tracing, and advising (see Advising Emacs Lisp Functions). Since ease of
debugging and the flexibility of redefining functions are important
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
to verify that using
defun actually has performance problems.
After an inline function is defined, its inline expansion can be performed later on in the same file, just like macros.
It’s possible to use
defmacro to define a macro to expand
into the same code that an inline function would execute
(see Macros). But the macro would be limited to direct use in
expressions—a macro cannot be called with
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
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
Alternatively, you can define a function by providing the code which will inline it as a compiler macro. The following macros make this possible.
Define a function name by providing code that does its inlining, as a compiler macro. The function will accept the argument list args and will have the specified body.
If present, doc should be the function’s documentation string
(see Documentation Strings of Functions); declare, if present, should be
declare form (see The
declare Form) specifying the function’s
Functions defined via
define-inline have several advantages
with respect to macros defined by
mapcar(see Mapping Functions).
cl-defsubst(see Argument Lists in Common Lisp Extensions for GNU Emacs Lisp).
defmacro, a function inlined with
inherits the scoping rules, either dynamic or lexical, from the call
site. See Scoping Rules for Variable Bindings.
The following macros should be used in the body of a function defined
Quote expression for
define-inline. This is similar to
the backquote (see Backquote), but quotes code and accepts only
This provides a convenient way to ensure that the arguments to an inlined function are evaluated exactly once, as well as to create local variables.
It’s similar to
let (see Local Variables): It sets up local
variables as specified by bindings, and then evaluates
body with those bindings in effect.
Each element of bindings should be either a symbol or a list of
(var expr); the result is to evaluate
expr and bind var to the result. However, when an element
of bindings is just a symbol var, the result of evaluating
var is re-bound to var (which is quite different from the
The tail of bindings can be either
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.
nil if the value of expression is already
Return the value of expression.
Signal an error, formatting args according to format.
Here’s an example of using
(define-inline myaccessor (obj) (inline-letevals (obj) (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))
This is equivalent to
(defsubst myaccessor (obj) (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2)))