Declares a variable as special, provides advice to the Common Lisp system, or helps the programmer to optimize code.
The special form
declare
behaves computationally as if it is not present (other than to affect the semantics), and is only allowed in certain contexts, such as after the variable list in a
let
,
do
,
defun
and so on.
(Consult the syntax definition of each special form to see if it takes
declare
forms and/or documentation strings.)
There are three distinct uses of
declare
: one is to declare Lisp variables as "special" (this affects the semantics of the appropriate bindings of the variables), the second is to provide advice to help the Common Lisp system (in reality the compiler) run your Lisp code faster or with more sophisticated debugging options, and the third (using the
:explain
declaration) is to help you optimize your code.
If you use
declare
to specify types (and so eliminate type-checking for the specified symbols) and then supply the wrong type, you may obtain a "Segmentation Violation". You can check this by interpreting the code (rather than compiling it).
The following are extensions to the Common Lisp definition of
declare
:
lambda-list
specifies the value to be returned when a programmer asks for the arglist of a function.
values
specifies the value to be returned when you ask for a description of the results of a function.
hcl:invisible-frame
specifies that calls to this function should not appear in a debugger backtrace.
hcl:alias
specifies that calls to this function should be displayed as calls to an alternative function in a debugger backtrace.
:explain
controls messages printed by the compiler while it is processing forms.
The remainder of this description documents the syntax and use of
:explain
declarations.
declaration ::= (:explain option *)
option ::= optionkey | ( optionkey optionvalue )
optionkey ::= :none | :variables | :types | :floats | :non-floats | :all-calls | :all-calls-with-arg-types | :calls | :boxing | :print-original-form | :print-expanded-form | :print-length | :print-level
The
:explain
declaration controls messages printed by the compiler while it is processing forms. The declaration can be used with proclaim or declaim as a top level form to give it global or file scope. It can also be used at the start of a
#'lambda
form or function body to give it the scope of that function. The declaration has unspecified effect when used in other contexts, for example in the body of a
let
form.
An
:explain
declaration consists of a set of options of the form
(
optionkey
optionvalue
)
which associates
optionvalue
with
optionkey
or
optionkey
which associates
t
with
optionkey
. By default, all of the
optionkey
s have an associated value
nil
. All
optionkey
s not specified by a declaration remain unchanged (except for the special action of the
:none
optionkey
described below).
The optionkey should be one of the following:
Set value associated with all
optionkey
s to
nil
. This turns off all explanations.
If
optionvalue
is non-
nil
, list all the variables of each function, specifying whether they are floating point or not.
If
optionvalue
is non-
nil
, print information about compiler transformations that depend on declared or deduced type information.
If
optionvalue
is non-
nil
, print information about calls to functions that may allocate floats.
If
optionvalue
is non-
nil
, print information about calls to functions that may allocate non-float numbers, for example bignums.
If
optionvalue
is non-
nil
, print information about calls to normal functions.
If
optionvalue
is non-
nil
, print the argument types for calls to normal functions. Must be combined with
:all-calls
.
A synonym for
:all-calls
.
If
optionvalue
is non-
nil
, print information about calls to functions that may allocate numbers, for example floats or bignums.
If
optionvalue
is non-
nil
, modifies the
:all-calls
,
:floats
and
:non-floats
explanations to include the original source code form that contains the call.
If
optionvalue
is non-
nil
, modifies the
:all-calls
,
:floats
and
:non-floats
explanations to include the macroexpanded source code form that contains the call.
Use the
optionvalue
as the value of
*print-length*
for
:all-calls
,
:floats
and
:non-floats
explanations.
Use the
optionvalue
as the value of
*print-level*
for
:all-calls
,
:floats
and
:non-floats
explanations.
(defun foo (arg)
(declare
(:explain :variables)
(optimize (float 0)))
(let* ((double-arg (coerce arg 'double-float))
(next (+ double-arg 1d0))
(other (* double-arg 1/2)))
(values next other)))
;;- Variables with non-floating point types:
;;- ARG OTHER
;;- Variables with floating point types:
;;- DOUBLE-ARG NEXT