Next: , Previous: , Up: GNU Emacs Common Lisp Emulation [Contents][Index]


7 Declarations

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: proclaim, declaim, and the.

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 default. Otherwise these declarations will effectively be ignored.

Function: cl-proclaim decl-spec

This function records a “global” declaration specified by decl-spec. Since cl-proclaim is a function, decl-spec is evaluated and thus should normally be quoted.

Macro: cl-declaim decl-specs…

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-declaim macro 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 cl-declaim form.)

Macro: cl-the type form

cl-the returns 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.

For example, mapcar can map over both lists and arrays. It is hard for the compiler to expand mapcar into 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-proclaim or cl-declaim should be a list beginning with a symbol that says what kind of declaration it is. This package currently understands special, inline, notinline, optimize, and warn declarations. (The warn declaration is an extension of standard Common Lisp.) Other Common Lisp declarations, such as type and ftype, are silently ignored.

special

Since all variables in Emacs Lisp are “special” (in the Common Lisp sense), special declarations 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.

In top-level contexts, it is generally better to write (defvar var) than (cl-declaim (special var)), since defvar makes your intentions clearer.

inline

The inline decl-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 cl-acons is declared inline by this package so that the form (cl-acons key value alist) will expand directly into (cons (cons key value) alist) 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.

notinline

The notinline declaration lists functions which should not be inlined after all; it cancels a previous inline declaration.

optimize

This declaration controls how much optimization is performed by the compiler.

The word 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 speed and 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 byte-optimize flag, which is set to nil for (speed 0) and to t for higher settings; and the safety quality is tied to the byte-compile-delete-errors flag, which is set to nil for (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 at run-time.)

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.

The optimize declaration is normally used in a top-level cl-proclaim or cl-declaim in a file.

warn

This declaration controls what sorts of warnings are generated by the byte compiler. The word warn is followed by any number of “warning qualities”, similar in form to optimization qualities. The currently supported warning types are redefine, callargs, unresolved, and 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-warnings for more details.


Next: Symbols, Previous: Macros, Up: GNU Emacs Common Lisp Emulation [Contents][Index]

AltStyle によって変換されたページ (->オリジナル) /