All Manuals > LispWorks® User Guide and Reference Manual > 37 The HCL Package

analyzing-special-variables-usage Macro


Prints an analysis of proclaimed symbols seen during compilation, as an aid to improving declarations.




analyzing-special-variables-usage (&key all default maybe-globals maybe-dynamics unused only-bound wrong-global inconsistent stream) &body body => results

A boolean.
A boolean.
A boolean.
A boolean.
A boolean.
A boolean.
A boolean.
A boolean.
t or an output stream.
Lisp forms that call the compiler.
The results of running body.

The macro analyzing-special-variables-usage executes the code in body, which needs to call the compiler, typically many times (compiling a whole system, for example). When body exits, it prints a simple analysis of symbols that were proclaimed and how they were proclaimed, in a way that is intended to be helpful in improving declarations. For a full explanation of how you might add or alter declarations, see 9.7.6 Usage of special variables.

The analysis is based solely on what the compiler sees, ignoring what is already in the image. It also ignores inline declarations.

Only symbols for which the compiler sees a special proclamation are reported (including cl:defvar, cl:defparameter, defglobal-parameter and defglobal-variable, but not cl:defconstant).

all and default are convenience arguments to control groups of the other keyword arguments, which are all boolean flags. The default value of all is nil. all provides the default value of maybe-globals and maybe-dynamics. The default value of default is t. default provides the default value of unused, only-bound, wrong-global and inconsistent.

stream determines where the analysis goes, and is interpreted as if by cl:format. It does not affect any of the I/O in body. The default value of stream is t, meaning standard output.

inconsistent controls whether to print symbols where the declaration and usage is inconsistent. Inconsistencies include:

  1. Accessing or binding the symbol before the proclamation.
  2. Multiple declarations which are different (for example, change from hcl:special-dynamic to cl:special)

The messages controlled by inconsistent are the most useful. A well written program should not produce any such message.

unused controls whether to report symbols that are proclaimed special but are otherwise not used. For this option to be really useful, body needs to force compile many source files.

Since such unused variables do not affect the code, unused is normally useful only for finding and eliminating dead declarations, but it can also flag situations when the wrong variable is used (if the variable that is supposed to be used is not used elsewhere).

only-bound controls whether to report symbols that have been seen bound, but whose value has not been read. The comments about unused also apply to only-bound.

wrong-global controls whether to print symbols that are bound but are also proclaimed hcl:special-global. If the proclamation preceded the binding, the compiler will signal a compiler-error.

maybe-globals controls whether to report symbols that were not seen bound. If these symbols are really never bound, they can be proclaimed global by defining them with defglobal-parameter and defglobal-variable, or proclaim with hcl:special-global (see declare), both for speed and also to prevent them getting bound by mistake.

It is quite useful to force compile a program each now and then with maybe-globals true, then check through the report and proclaim global all those symbols that can be proclaimed global.

maybe-dynamics controls whether to report symbols that have been seen bound, and are proclaimed special, but not hcl:special-dynamic or hcl:special-global. Some of these may be proclaimed hcl:special-dynamic.

The report that is generated is grouped according to the file in which a proclamation was found. If a variable was proclaimed in multiple files, it will appear multiple times in the output. Within each file the output is grouped according to what is reported.

For the keyword arguments except inconsistent, the symbols are simply listed. For inconsistent, it outputs several lines for each symbol. Each line starts with one of the symbols cl:special, hcl:special-global, hcl:special-dynamic, hcl:special-fast-access (these four signify a proclamation), :bound or :accessed (these two indicate the usage). It is followed by the pathname of the file in which this one found. Only occurrences which give rise to inconsistency are listed.


The report about inconsistent usage is almost always useful. unused and only-bound are mostly useful when body force compiles many files, though they have limited utility in partial compilation too. maybe-globals and maybe-dynamics need full compilation to be really useful. Of the latter maybe-globals is the more useful.

See also


LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:35