declare (original) (raw)
ANSI Common Lisp 3 Evaluation and Compilation
3.8 Dictionary Evaluation and Compilation
Syntax:
declare {declaration-specifier}*
Arguments:
declaration-specifier - a declaration specifier; not evaluated.
Description:
A declare expression, sometimes called a declaration, can occur only at the beginning of the bodies of certain forms; that is, it may be preceded only by other declare expressions, or by a documentation string if the context permits.
A declare expression can occur in a _lambda expression_or in any of the forms listed in the next figure.
Standardized Forms In Which Declarations Can Occur
defgeneric | do-external-symbols | prog |
---|---|---|
define-compiler-macro | do-symbols | prog* |
define-method-combination | dolist | restart-case |
define-setf-expander | dotimes | symbol-macrolet |
defmacro | flet | with-accessors |
defmethod | handler-case | with-hash-table-iterator |
defsetf | labels | with-input-from-string |
deftype | let | with-open-file |
defun | let* | with-open-stream |
destructuring-bind | locally | with-output-to-string |
do | macrolet | with-package-iterator |
do* | multiple-value-bind | with-slots |
do-all-symbols | pprint-logical-block |
A declare expression can only occur where specified by the syntax of these forms. The consequences of attempting to evaluate a declare _expression_are undefined. In situations where such expressions can appear, explicit checks are made for their presence and they are never actually evaluated; it is for this reason that they are called "declare expressions" rather than "declare forms."
Macro forms cannot expand into declarations;declare expressions must appear as actual subexpressions of the form to which they refer.
The next figure shows a list of _declaration identifiers_that can be used with declare.
Local Declaration Specifiers
dynamic-extent | ignore | optimize |
---|---|---|
ftype | inline | special |
ignorable | notinline | type |
An implementation is free to support other (implementation-defined)declaration identifiers as well.
Examples:
(defun nonsense (k x z) (foo z x) ;First call to foo (let ((j (foo k x)) ;Second call to foo (x (* k k))) (declare (inline foo) (special x z)) (foo x j z))) ;Third call to foo
In this example, the inline declaration applies only to the third call to foo, but not to the first or second ones. The special declaration of x causes letto make a dynamic binding for x, and causes the reference to xin the body of let to be a dynamic reference. The reference to x in the second call to foo is a local reference to the second parameter of nonsense. The reference to x in the first call to foo is a local reference, not a special one. The special declaration of zcauses the reference to z in the third call to foo to be a dynamic reference; it does not refer to the parameter to nonsense named z, because that parameter binding has not been declared to be special. (The special declaration of z does not appear in the body of defun, but in an inner form, and therefore does not affect the binding of the parameter.)
Exceptional Situations:
The consequences of trying to use a declare expression as a form to be evaluated are undefined.
See Also:
proclaim, Section 4.2.3 Type Specifiers,declaration,dynamic-extent,ftype,ignorable,ignore,inline,notinline,optimize,type
Allegro CL Implementation Details:
None.