Common Lisp includes a complex and powerful “declaration”
mechanism that allows you to give the compiler special hints
about the types of data that will be stored in particular variables,
and about the ways those variables and functions will be used. This
package defines versions of all the Common Lisp declaration forms:
Most of the Common Lisp declarations are not currently useful in Emacs Lisp. For example, the byte-code system provides little opportunity to benefit from type information. A few declarations are meaningful when byte compiler optimizations are enabled, as they are by the default. Otherwise these declarations will effectively be ignored.
This function records a “global” declaration specified by decl-spec. Since
cl-proclaimis a function, decl-spec is evaluated and thus should normally be quoted.
This macro is like
cl-proclaim, except that it takes any number of decl-spec arguments, and the arguments are unevaluated and unquoted. The
cl-declaimmacro also puts
(cl-eval-when (compile load eval) ...)around the declarations so that they will be registered at compile-time as well as at run-time. (This is vital, since normally the declarations are meant to influence the way the compiler treats the rest of the file that contains the
This macro is used to make declarations within functions and other code. Common Lisp allows declarations in various locations, generally at the beginning of any of the many “implicit
progns” throughout Lisp syntax, such as function bodies,
letbodies, etc. Currently the only declaration understood by
In this package,
cl-locallyis no different from
cl-thereturns the value of
form, first checking (if optimization settings permit) that it is of type
type. Future byte-compiler optimizations may also make use of this information to improve runtime efficiency.
mapcarcan map over both lists and arrays. It is hard for the compiler to expand
mapcarinto an in-line loop unless it knows whether the sequence will be a list or an array ahead of time. With
(mapcar 'car (cl-the vector foo)), a future compiler would have enough information to expand the loop in-line. For now, Emacs Lisp will treat the above code as exactly equivalent to
(mapcar 'car foo).
Each decl-spec in a
cl-declare should be a list beginning with a symbol that says
what kind of declaration it is. This package currently understands
warn declarations. (The
warn declaration is an
extension of standard Common Lisp.) Other Common Lisp declarations,
ftype, are silently ignored.
specialdeclarations are only advisory. They simply tell the byte compiler that the specified variables are intentionally being referred to without being bound in the body of the function. The compiler normally emits warnings for such references, since they could be typographical errors for references to local variables.
(cl-declare (special var1 var2
) (defvar var2
In top-level contexts, it is generally better to write
(cl-declaim (special var
defvar makes your intentions clearer.
inlinedecl-spec lists one or more functions whose bodies should be expanded “in-line” into calling functions whenever the compiler is able to arrange for it. For example, the function
inlineby this package so that the form
(cl-aconskey value alist
)will expand directly into
(cons (conskey value
)when it is called in user functions, so as to save function calls.
The following declarations are all equivalent. Note that the
defsubst form is a convenient way to define a function
and declare it inline all at once.
(cl-declaim (inline foo bar)) (cl-eval-when (compile load eval) (cl-proclaim '(inline foo bar))) (defsubst foo (...) ...) ; instead of defun
Please note: this declaration remains in effect after the containing source file is done. It is correct to use it to request that a function you have defined should be inlined, but it is impolite to use it to request inlining of an external function.
In Common Lisp, it is possible to use
(declare (inline ...))
before a particular call to a function to cause just that call to
be inlined; the current byte compilers provide no way to implement
(cl-declare (inline ...)) is currently ignored by
notinlinedeclaration lists functions which should not be inlined after all; it cancels a previous
optimize is followed by any number of lists like
(speed 3) or
(safety 2). Common Lisp defines several
optimization “qualities”; this package ignores all but
safety. The value of a quality should be an integer from
0 to 3, with 0 meaning “unimportant” and 3 meaning “very important”.
The default level for both qualities is 1.
In this package, the
speed quality is tied to the
flag, which is set to
(speed 0) and to
t for higher settings; and the
safety quality is
tied to the
byte-compile-delete-errors flag, which is
(safety 3) and to
t for all
lower settings. (The latter flag controls whether the compiler
is allowed to optimize out code whose only side-effect could
be to signal an error, e.g., rewriting
(progn foo bar) to
bar when it is not known whether
foo will be bound
Note that even compiling with
(safety 0), the Emacs
byte-code system provides sufficient checking to prevent real
harm from being done. For example, barring serious bugs in
Emacs itself, Emacs will not crash with a segmentation fault
just because of an error in a fully-optimized Lisp program.
optimize declaration is normally used in a top-level
cl-declaim in a file; Common Lisp allows
it to be used with
declare to set the level of optimization
locally for a given form, but this will not work correctly with the
current byte-compiler. (The
will set the new optimization level, but that level will not
automatically be unset after the enclosing form is done.)
warnis followed by any number of “warning qualities”, similar in form to optimization qualities. The currently supported warning types are
free-vars; in the current system, a value of 0 will disable these warnings and any higher value will enable them. See the documentation of the variable
byte-compile-warningsfor more details.