Affects only variable bindings and specifies that the vars take on values only of the specified typespec. In particular, values assigned to the variables by setq, as well as the initial values of the vars must be of the specified typespec. type declarations never apply to function bindings (see ftype).

The meaning of a type declaration is equivalent to changing each reference to a variable (var) within the scope of the declaration to (the typespecvar), changing each expression assigned to the variable (new-value) within the scope of the declaration to (the typespecnew-value), and executing (the typespecvar) at the moment the scope of the declaration is entered.

A type declaration is valid in all declarations. The interpretation of a type declaration is as follows:

1. During the execution of any reference to the declared variable within the scope of the declaration, the consequences are undefined if the value of the declared variable is not of the declared type.

2. During the execution of any setq of the declared variable within the scope of the declaration, the consequences are undefined if the newly assigned value of the declared variable is not of the declared type.

3. At the moment the scope of the declaration is entered, the consequences are undefined if the value of the declared variable is not of the declared type.

If nested type declarations refer to the same variable, then the value of the variable must be a member of the intersection of the declared types.

If there is a local type declaration for a dynamic variable, and there is also a global type proclamation for that same variable, then the value of the variable within the scope of the local declaration must be a member of the intersection of the two declared types.

A type declaration for the arguments to a function does not necessarily imply anything about the type of the result. The following function is not permitted to be compiled using implementation-dependentfixnum-only arithmetic:

(defun f (x y) (declare (fixnum x y)) (+ x y))

To see why, consider (f most-positive-fixnum 1). Common Lisp defines that F must return a bignum here, rather than signal an error or produce a mathematically incorrect result. If you have special knowledge such ``fixnum overflow'' cases will not come up, you can declare the result value to be in the fixnum range, enabling some compilers to use more efficient arithmetic:

(defun f (x y)
(declare (fixnum x y))
(the fixnum (+ x y)))

Note, however, that in the three-argument case, because of the possibility of an implicit intermediate value growing too large, the following will not cause implementation-dependentfixnum-only arithmetic to be used:

(defun f (x y)
(declare (fixnum x y z))
(the fixnum (+ x y z)))

To see why, consider (f most-positive-fixnum 1 -1). Although the arguments and the result are all fixnums, an intermediate value is not a fixnum. If it is important that implementation-dependentfixnum-only arithmetic be selected in implementations that provide it, consider writing something like this instead: