ECL supports all kinds of declarations described in the [see Steele:84]. Any valid declaration will affect the ECL environment in some way or another, although information obtained by declarations, other than special declarations, is mainly used by the ECL compiler.
As described in [see Steele:84], Common-Lisp declarations are divided into two
classes: proclamations and others. A proclamation is a global
declaration given by the function
proclaim, the top-level macro
defvar, or the top-level macro
defparameter. Once given, a
proclamation remains effective during the ECL session unless it is shadowed
by a local declaration or is canceled by another proclamation. Any other
declaration is a local declaration and is given only by the special form
declare. A local declaration remains in effect only within the body of
the construct that surrounds the declaration.
In the following nonsensical example borrowed from Chapter 9 of [see Steele:84],
(defun nonsense (k x z) (foo z x) (let ((j (foo k x)) (x (* k k))) (declare (inline foo) (special x z)) (foo x j z)))
inline and the special declarations both remain in effect within the
let form. In this case, we say that the
let form is
the surrounding construct of these declarations.
The ECL interpreter does actually check whether the value of the form conforms to the data type specified by value-type and signals an error if the value does not. The type checking is performed by the function
typep. For example,
(the fixnum (foo))
is equivalent to
(let ((values (multiple-value-list (foo)))) (cond ((endp values) (error ``Too few return values.")) ((not (endp (cdr values))) (error ``Too many return values.")) ((typep (car values) 'fixnum) (car values)) (t (error ``~s is not of type fixnum." (car values)))))
On the other hand, the ECL compiler uses the special form to obtain type information for compiled code optimization. No code for runtime type-checking is embedded in the compiled code.