788 lines
35 KiB
HTML
788 lines
35 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
|
|
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
|
|
<HEAD>
|
|
<TITLE>9.2. Declaration Specifiers</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
<meta name="description" value=" Declaration Specifiers">
|
|
<meta name="keywords" value="clm">
|
|
<meta name="resource-type" value="document">
|
|
<meta name="distribution" value="global">
|
|
<P>
|
|
<b>Common Lisp the Language, 2nd Edition</b>
|
|
<BR> <HR><A NAME=tex2html2831 HREF="node106.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html2829 HREF="node103.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html2823 HREF="node104.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html2833 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html2834 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
|
<B> Next:</B> <A NAME=tex2html2832 HREF="node106.html"> Type Declaration for </A>
|
|
<B>Up:</B> <A NAME=tex2html2830 HREF="node103.html"> Declarations</A>
|
|
<B> Previous:</B> <A NAME=tex2html2824 HREF="node104.html"> Declaration Syntax</A>
|
|
<HR> <P>
|
|
<H1><A NAME=SECTION001320000000000000000>9.2. Declaration Specifiers</A></H1>
|
|
<P>
|
|
<A NAME=DECLARATIONSPECIFIERSSECTION>Here</A>
|
|
is a list of valid declaration specifiers for use in
|
|
<tt>declare</tt>. A construct is said to be ``affected'' by a declaration
|
|
if it occurs within the scope of a declaration.
|
|
<P>
|
|
<DL COMPACT><DT><tt>special</tt>
|
|
<DD>
|
|
<tt>(special <i>var1</i> <i>var2</i> ...)</tt> specifies that all of
|
|
the variables named are to be considered <i>special</i>.
|
|
This specifier affects variable bindings but also pervasively
|
|
affects references.
|
|
All variable bindings affected are made to be dynamic bindings,
|
|
and affected variable references refer to the current dynamic binding
|
|
rather than to the current local binding.
|
|
For example:
|
|
<P><pre>
|
|
(defun hack (thing *mod*) ;The binding of the parameter
|
|
(declare (special *mod*)) ; <tt>*mod*</tt> is visible to <tt>hack1</tt>,
|
|
(hack1 (car thing))) ; but not that of <tt>thing</tt>
|
|
|
|
(defun hack1 (arg)
|
|
(declare (special *mod*)) ;Declare references to <tt>*mod*</tt>
|
|
; within <tt>hack1</tt> to be special
|
|
(if (atom arg) *mod*
|
|
(cons (hack1 (car arg)) (hack1 (cdr arg)))))
|
|
</pre><P>
|
|
Note that it is conventional, though not required, to give special
|
|
variables names that begin and end with an asterisk.
|
|
<P>
|
|
A <tt>special</tt> declaration does <i>not</i> affect bindings pervasively.
|
|
Inner bindings of a variable implicitly shadow
|
|
a <tt>special</tt> declaration and must be explicitly re-declared to
|
|
be special.
|
|
(However, a <tt>special</tt> proclamation <i>does</i> pervasively affect bindings;
|
|
this exception is made for reasons of
|
|
convenience and compatibility with MacLisp.)
|
|
For example:
|
|
<P><pre>
|
|
(proclaim '(special x)) ;<tt>x</tt> is always special
|
|
|
|
(defun example (x y)
|
|
(declare (special y))
|
|
(let ((y 3) (x (* x 2)))
|
|
(print (+ y (locally (declare (special y)) y)))
|
|
(let ((y 4)) (declare (special y)) (foo x))))
|
|
</pre><P>
|
|
In the contorted code above, the outermost and innermost bindings of
|
|
<tt>y</tt> are special and therefore dynamically scoped, but the middle
|
|
binding is lexically scoped. The two arguments to <tt>+</tt> are different,
|
|
one being the value, which is <tt>3</tt>, of the lexically bound variable
|
|
<tt>y</tt>, and the other being the value of the special variable named <tt>y</tt>
|
|
(a binding of which happens, coincidentally, to lexically surround it at
|
|
an outer level). All the bindings of <tt>x</tt> and references to <tt>x</tt>
|
|
are special, however, because of the proclamation that <tt>x</tt> is
|
|
always <tt>special</tt>.
|
|
<P>
|
|
As a matter of style, use of <tt>special</tt> proclamations should be
|
|
avoided. The <tt>defvar</tt> and <tt>defparameter</tt> macros
|
|
are the conventional means for proclaiming special variables
|
|
in a program.
|
|
<P>
|
|
<DT><tt>type</tt>
|
|
<DD>
|
|
<tt>(type <i>type</i> <i>var1</i> <i>var2</i> ...)</tt> affects
|
|
only variable bindings and specifies that the
|
|
variables mentioned will take on values only of the specified type.
|
|
In particular, values assigned to the variables by <tt>setq</tt>,
|
|
as well as the initial values of the variables, must be of
|
|
the specified type.
|
|
</dl>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT><DD>
|
|
X3J13 voted in January 1989
|
|
(DECLARE-TYPE-FREE) <A NAME=9325> </A>
|
|
to alter the interpretation of type declarations.
|
|
They are not to be construed to affect ``only variable bindings.''
|
|
The new rule for a declaration of a variable to
|
|
have a specified type is threefold:<p>
|
|
<UL><LI> It is an error if, during the execution
|
|
of any reference to that variable within the scope of the declaration,
|
|
the value of the variable is not of the declared type.<p>
|
|
<LI> It is an error if, during the execution
|
|
of a <tt>setq</tt> of that variable within the scope of the declaration,
|
|
the new value for the variable is not of the declared type.<p>
|
|
<LI> It is an error if, at any moment that execution enters the scope
|
|
of the declaration, the value of the variable is not of the
|
|
declared type.<p>
|
|
</UL>
|
|
One may think of a type declaration <tt>(declare (type face bodoni))</tt>
|
|
as implicitly changing every reference to <tt>bodoni</tt> within the scope
|
|
of the declaration to <tt>(the face bodoni)</tt>; changing every expression
|
|
<i>exp</i> assigned to <tt>bodoni</tt> within the scope of the declaration
|
|
to <tt>(the face <i>exp</i>)</tt>; and implicitly executing <tt>(the face bodoni)</tt>
|
|
every time execution enters the scope of the declaration.
|
|
<P>
|
|
These new rules make type declarations much more useful. Under first
|
|
edition rules, a type declaration was useless if not associated with
|
|
a variable binding; declarations such as in
|
|
<P><pre>
|
|
(locally
|
|
(declare (type (byte 8) x y))
|
|
(+ x y))
|
|
</pre><P>
|
|
at best had no effect and at worst were erroneous, depending on one's
|
|
interpretation of the first edition. Under the interpretation approved
|
|
by X3J13, such declarations have ``the obvious natural interpretation.''
|
|
<P>
|
|
X3J13 noted that if nested type declarations refer to the same variable,
|
|
then all of them have effect; the value of the variable must be a member of the
|
|
intersection of the declared types.
|
|
<P>
|
|
Nested type declarations could occur as a result of either macro expansion
|
|
or carefully crafted code. There are three cases. First,
|
|
the inner type might be a subtype of the outer one:
|
|
<P><pre>
|
|
(defun compare (apples oranges)
|
|
(declare (type number apples oranges))
|
|
(cond ((typep apples 'fixnum)
|
|
;; The programmer happens to know that, thanks to
|
|
;; constraints imposed by the caller, if APPLES
|
|
;; is a fixnum, then ORANGES will be also, and
|
|
;; therefore wishes to avoid the unnecessary cost
|
|
;; of checking ORANGES. Nevertheless the compiler
|
|
;; should be informed to allow it to optimize code.
|
|
(locally (declare (type fixnum apples oranges)))
|
|
;; Maybe the compiler could have figured
|
|
;; out by flow analysis that APPLES must
|
|
;; be a fixnum here, but it doesn't hurt
|
|
;; to say it explicitly.
|
|
(< apples oranges)))
|
|
((or (complex apples)
|
|
(complex oranges))
|
|
(error "Not yet implemented. Sorry."))
|
|
...))
|
|
</pre><P>
|
|
This is the case most likely to arise in code written completely by hand.
|
|
<P>
|
|
Second, the outer type might be a subtype of the inner one. In this
|
|
case the inner declaration has no additional practical effect, but
|
|
it is harmless. This is
|
|
likely to occur if code declares a variable to be of a very specific type
|
|
and then passes it to a macro that then declares it to be of a less
|
|
specific type.
|
|
<P>
|
|
Third, the inner and outer declarations might be for types that
|
|
overlap, neither being a subtype of the other. This is likely to occur
|
|
only as a result of macro expansion. For example, user code might
|
|
declare a variable to be of type <tt>integer</tt>, and a macro might
|
|
later declare it to be of type <tt>(or fixnum package)</tt>; in this case
|
|
a compiler could intersect the two types to determine that in this
|
|
instance the variable may hold only fixnums.
|
|
<P>
|
|
The reader should note that the following code fragment is,
|
|
perhaps astonishingly, <i>not in error</i> under the interpretation approved by
|
|
X3J13:
|
|
<P><pre>
|
|
(let ((james .007)
|
|
(maxwell 86))
|
|
(flet ((spy-swap ()
|
|
(rotatef james maxwell)))
|
|
(locally (declare (integer maxwell))
|
|
(spy-swap)
|
|
(view-movie "The Sound of Music")
|
|
(spy-swap)
|
|
maxwell)))
|
|
=> 86 (after a couple of hours of Julie Andrews)
|
|
</pre><P>
|
|
The variable <tt>maxwell</tt> is declared to be an integer over the <i>scope</i>
|
|
of the type declaration, not over its <i>extent</i>. Indeed <tt>maxwell</tt>
|
|
takes on the non-integer value <tt>.007</tt> while the Trapp family make their
|
|
escape, but because no
|
|
reference to <tt>maxwell</tt> within the scope of the declaration
|
|
ever produces a non-integer value, the code
|
|
is correct.
|
|
<P>
|
|
Now the assignment to <tt>maxwell</tt> during the first call
|
|
to <tt>spy-swap</tt>, and the reference to <tt>maxwell</tt> during the second call,
|
|
<i>do</i> involve non-integer values, but they occur within the body of
|
|
<tt>spy-swap</tt>, which is <i>not</i> in the scope of the type declaration!
|
|
One could put the declaration in a different place so as to include
|
|
<tt>spy-swap</tt> in the scope:
|
|
<P><pre>
|
|
(let ((james .007)
|
|
(maxwell 86))
|
|
(locally (declare (integer maxwell))
|
|
(flet ((spy-swap ()
|
|
(rotatef james maxwell)))
|
|
(spy-swap) ;Bug!
|
|
(view-movie "The Sound of Music")
|
|
(spy-swap)
|
|
maxwell)))
|
|
</pre><P>
|
|
and then the code is indeed in error.
|
|
<P>
|
|
X3J13 also voted in January 1989
|
|
(FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS) <A NAME=9364> </A>
|
|
to alter the meaning of the
|
|
<tt>function</tt> type specifier when used in <tt>type</tt> declarations
|
|
(see section <A HREF="node49.html#SPECIALIZEDTYPESPECIFIERSECTION">4.5</A>).
|
|
</dl>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<DL COMPACT>
|
|
<DT><i>type</i>
|
|
<DD>
|
|
<tt>(<i>type</i> <i>var1</i> <i>var2</i> ...)</tt>
|
|
is an abbreviation for
|
|
<tt>(type <i>type</i> <i>var1</i> <i>var2</i> ...)</tt>,
|
|
provided that <i>type</i> is one of the symbols appearing
|
|
in table <A HREF="node45.html#TYPESYMBOLSTABLE">4-1</A>.
|
|
</dl>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd> Observe that this covers the particularly common case of declaring
|
|
numeric variables:
|
|
<P><pre>
|
|
(declare (single-float mass dx dy dz)
|
|
(double-float acceleration sum))
|
|
</pre><P>
|
|
In many implementations there is also some advantage to declaring variables
|
|
to have certain specialized vector types such as <tt>base-string</tt>.
|
|
</dl>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<DL COMPACT>
|
|
<DT><tt>ftype</tt>
|
|
<DD>
|
|
<tt>(ftype <i>type</i> <i>function-name-1</i> <i>function-name-2</i> ...)</tt>
|
|
specifies that the named functions will be of the functional type
|
|
<i>type</i>, an example of which follows.
|
|
For example:
|
|
<P><pre>
|
|
(declare (ftype (function (integer list) t) nth)
|
|
(ftype (function (number) float) sin cos))
|
|
</pre><P>
|
|
Note that rules of lexical scoping are observed; if one of the functions
|
|
mentioned has a lexically apparent local definition
|
|
(as made by <tt>flet</tt> or <tt>labels</tt>), then the declaration
|
|
applies to that local definition and not to the global function definition.
|
|
</dl>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
X3J13 voted in March 1989 (FUNCTION-NAME) <A NAME=9393> </A> to extend <tt>ftype</tt>
|
|
declaration specifiers
|
|
to accept any function-name (a symbol or a list
|
|
whose <i>car</i> is <tt>setf</tt> - see section <A HREF="node77.html#FUNCTIONNAMESECTION">7.1</A>).
|
|
Thus one may write
|
|
<P><pre>
|
|
(declaim (ftype (function (list) t) (setf cadr)))
|
|
</pre><P>
|
|
to indicate the type of the <tt>setf</tt> expansion function for <tt>cadr</tt>.
|
|
<P>
|
|
X3J13 voted in January 1989
|
|
(FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS) <A NAME=9404> </A>
|
|
to alter the meaning of the
|
|
<tt>function</tt> type specifier when used in <tt>ftype</tt> declarations
|
|
(see section <A HREF="node49.html#SPECIALIZEDTYPESPECIFIERSECTION">4.5</A>).
|
|
</dl>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<P>
|
|
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif"><br>
|
|
<DL COMPACT><DT><tt>function</tt>
|
|
<DD>
|
|
<tt>(function <i>name</i> <i>arglist</i> <i>result-type1</i> <i>result-type2</i> ...)</tt>
|
|
is entirely equivalent to
|
|
<P><pre>
|
|
<tt>(ftype (function <i>arglist</i> <i>result-type1</i> <i>result-type2</i> ...) <i>name</i>)</tt>
|
|
</pre><P>
|
|
but may be more convenient for some purposes.
|
|
For example:
|
|
<P><pre>
|
|
(declare (function nth (integer list) t)
|
|
(function sin (number) float)
|
|
(function cos (number) float))
|
|
</pre><P>
|
|
The syntax mildly resembles that of <tt>defun</tt>: a function-name,
|
|
then an argument list, then a specification of results.
|
|
<P>
|
|
Note that rules of lexical scoping are observed; if one of the functions
|
|
mentioned has a lexically apparent local definition
|
|
(as made by <tt>flet</tt> or <tt>labels</tt>), then the declaration
|
|
applies to that local definition and not to the global function definition.
|
|
</DL>
|
|
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
|
|
<P>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
|
|
X3J13 voted in January 1989
|
|
(DECLARE-FUNCTION-AMBIGUITY) <A NAME=9431> </A>
|
|
to remove this interpretation
|
|
of the <tt>function</tt> declaration specifier from the language.
|
|
Instead, a declaration specifier
|
|
<P><pre>
|
|
(function <i>var1</i> <i>var2</i> ...)
|
|
</pre><P>
|
|
is to be treated simply as an abbreviation for
|
|
<P><pre>
|
|
(type function <i>var1</i> <i>var2</i> ...)
|
|
</pre><P>
|
|
just as for all other symbols appearing in table <A HREF="node45.html#TYPESYMBOLSTABLE">4-1</A>.
|
|
<P>
|
|
X3J13 noted that although <tt>function</tt> appears in
|
|
table <A HREF="node45.html#TYPESYMBOLSTABLE">4-1</A>, the first edition also discussed it
|
|
explicitly, with a different meaning,
|
|
without noting whether the differing
|
|
interpretation was to replace or augment the
|
|
interpretation regarding table <A HREF="node45.html#TYPESYMBOLSTABLE">4-1</A>. Unfortunately
|
|
there is an ambiguous case: the declaration
|
|
<P><pre>
|
|
(declare (function foo nil string))
|
|
</pre><P>
|
|
can be construed to abbreviate either
|
|
<P><pre>
|
|
(declare (ftype (function () string) foo))
|
|
</pre><P>
|
|
or
|
|
<P><pre>
|
|
(declare (type function foo nil string))
|
|
</pre><P>
|
|
The latter could perhaps be rejected on semantic grounds: it would be an
|
|
error to declare <tt>nil</tt>, a constant, to be of type <tt>function</tt>.
|
|
In any case, X3J13 determined that the ice was too thin here;
|
|
the possibility of confusion is not worth the convenience of
|
|
an abbreviation for <tt>ftype</tt> declarations.
|
|
The change also makes the language more consistent.
|
|
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<P>
|
|
<DL COMPACT><DT><tt>inline</tt>
|
|
<DD>
|
|
<tt>(inline <i>function1</i> <i>function2</i> ...)</tt> specifies that
|
|
it is desirable for the compiler to open-code
|
|
calls to the specified functions; that is, the code for a specified function
|
|
should be integrated into the calling routine, appearing in-line
|
|
in place of a procedure call. This may achieve
|
|
extra speed at the expense of debuggability (calls to functions
|
|
compiled in-line cannot be traced, for example).
|
|
This declaration is pervasive.
|
|
Remember that
|
|
a compiler is free to ignore this declaration.
|
|
<P>
|
|
Note that rules of lexical scoping are observed; if one of the functions
|
|
mentioned has a lexically apparent local definition
|
|
(as established by <tt>flet</tt> or <tt>labels</tt>), then the declaration
|
|
applies to that local definition and not to the global function definition.
|
|
</dl>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
X3J13 voted in October 1988 (PROCLAIM-INLINE-WHERE) <A NAME=9462> </A>
|
|
to clarify that during compilation the <tt>inline</tt> declaration specifier
|
|
serves two distinct purposes: it indicates not only that affected calls
|
|
to the specified functions should be expanded in-line, but also that
|
|
affected definitions of the specified functions must be recorded for
|
|
possible use in performing such expansions.
|
|
<P>
|
|
Looking at it the other way,
|
|
the compiler is not required to save function definitions against the
|
|
possibility of future expansions unless the functions have already been
|
|
proclaimed to be <tt>inline</tt>. If a function is proclaimed (or declaimed)
|
|
<tt>inline</tt>
|
|
before some call to that function but the current definition of that
|
|
function was established before the proclamation was processed,
|
|
it is implementation-dependent whether that call will be expanded in-line.
|
|
(Of course, it is implementation-dependent anyway, because a compiler
|
|
is always free to ignore <tt>inline</tt> declaration specifiers.
|
|
However, the intent of the committee is clear: for best results,
|
|
the user is advised to put any <tt>inline</tt> proclamation of
|
|
a function before any definition of or call to that function.)
|
|
<P>
|
|
Consider these examples:
|
|
<P><pre>
|
|
(defun huey (x) (+ x 100)) ;Compiler need not remember this
|
|
(declaim (inline huey dewey))
|
|
(defun dewey (y) (huey (sqrt y))) ;Call to <tt>huey</tt> unlikely to be expanded
|
|
(defun louie (z) (dewey (/ z))) ;Call to <tt>dewey</tt> likely to be expanded
|
|
</pre><P>
|
|
X3J13 voted in March 1989 (FUNCTION-NAME) <A NAME=9473> </A> to extend <tt>inline</tt>
|
|
declaration specifiers
|
|
to accept any function-name (a symbol or a list
|
|
whose <i>car</i> is <tt>setf</tt> - see section <A HREF="node77.html#FUNCTIONNAMESECTION">7.1</A>).
|
|
Thus one may write <tt>(declare (inline (setf cadr)))</tt> to indicate
|
|
that the <tt>setf</tt>
|
|
expansion function for <tt>cadr</tt> should be compiled in-line.
|
|
</dl>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<DL COMPACT>
|
|
<DT><tt>notinline</tt>
|
|
<DD>
|
|
<tt>(notinline <i>function1</i> <i>function2</i> ...)</tt> specifies that it is
|
|
<i>undesirable</i> to compile the specified functions in-line.
|
|
This declaration is pervasive.
|
|
A compiler is <i>not</i> free to ignore this declaration.
|
|
<P>
|
|
Note that rules of lexical scoping are observed; if one of the functions
|
|
mentioned has a lexically apparent local definition
|
|
(as made by <tt>flet</tt> or <tt>labels</tt>), then the declaration
|
|
applies to that local definition and not to the global function definition.
|
|
</dl>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
X3J13 voted in March 1989 (FUNCTION-NAME) <A NAME=9490> </A> to extend <tt>notinline</tt>
|
|
declaration specifiers
|
|
to accept any function-name (a symbol or a list
|
|
whose <i>car</i> is <tt>setf</tt> - see section <A HREF="node77.html#FUNCTIONNAMESECTION">7.1</A>).
|
|
Thus one may write <tt>(declare (notinline (setf cadr)))</tt> to indicate
|
|
that the <tt>setf</tt>
|
|
expansion function for <tt>cadr</tt> should not be compiled in-line.
|
|
<P>
|
|
X3J13 voted in January 1989
|
|
(ALLOW-LOCAL-INLINE) <A NAME=9500> </A>
|
|
to clarify that the proper way to define a function <tt>gnards</tt>
|
|
that is not <tt>inline</tt> by default, but for which a local
|
|
declaration <tt>(declare (inline gnards))</tt> has half a chance of
|
|
actually compiling <tt>gnards</tt> in-line, is as follows:
|
|
<P><pre>
|
|
(declaim (inline gnards))
|
|
|
|
(defun gnards ...)
|
|
|
|
(declaim (notinline gnards))
|
|
</pre><P>
|
|
The point is that the first declamation informs the compiler that
|
|
the definition of <tt>gnards</tt> may be needed later for in-line expansion,
|
|
and the second declamation prevents any expansions unless and until it is
|
|
overridden.
|
|
<P>
|
|
While an implementation is never required to perform in-line expansion,
|
|
many implementations that do support such expansion will not
|
|
process <tt>inline</tt> requests successfully unless definitions are
|
|
written with these proclamations in the manner shown above.
|
|
</dl>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<DL COMPACT>
|
|
<DT><tt>ignore</tt>
|
|
<DD>
|
|
<tt>(ignore <i>var1</i> <i>var2</i> ... <i>varn</i>)</tt> affects only variable bindings
|
|
and specifies that the bindings
|
|
of the specified variables are never used. It is desirable for a compiler
|
|
to issue a warning if a variable so declared is ever referred to
|
|
or is also declared special, or if a variable is lexical, never referred to,
|
|
and not declared to be ignored.
|
|
<P>
|
|
<DT><tt>optimize</tt>
|
|
<DD>
|
|
<tt>(optimize (<i>quality1</i> <i>value1</i>) (<i>quality2</i> <i>value2</i>)...)</tt>
|
|
advises the compiler that each <i>quality</i> should be given attention
|
|
according to the specified corresponding <i>value</i>.
|
|
A quality is a symbol; standard qualities
|
|
include <tt>speed</tt> (of the object code), <tt>space</tt> (both code size and
|
|
run-time space), <tt>safety</tt> (run-time error checking),
|
|
and <tt>compilation-speed</tt> (speed of the compilation process).
|
|
</dl>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
X3J13 voted in October 1988 (OPTIMIZE-DEBUG-INFO) <A NAME=9526> </A> to add
|
|
the standard quality <tt>debug</tt> (ease of debugging).
|
|
</dl>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
Other qualities may be recognized by particular implementations.
|
|
A <i>value</i> should be a non-negative integer, normally in the range
|
|
<tt>0</tt> to <tt>3</tt>. The value <tt>0</tt> means that the quality is totally
|
|
unimportant, and <tt>3</tt> that the quality is extremely important;
|
|
<tt>1</tt> and <tt>2</tt> are intermediate values, with <tt>1</tt> the ``normal''
|
|
or ``usual'' value.
|
|
One may abbreviate <tt>(<i>quality</i> 3)</tt> to simply <i>quality</i>.
|
|
This declaration is pervasive.
|
|
For example:
|
|
<P><pre>
|
|
(defun often-used-subroutine (x y)
|
|
(declare (optimize (safety 2)))
|
|
(error-check x y)
|
|
(hairy-setup x)
|
|
(do ((i 0 (+ i 1))
|
|
(z x (cdr z)))
|
|
((null z) i)
|
|
;; This inner loop really needs to burn.
|
|
(declare (optimize speed))
|
|
(declare (fixnum i))
|
|
)))
|
|
</pre><P>
|
|
<P>
|
|
<DT><tt>declaration</tt>
|
|
<DD>
|
|
<tt>(declaration <i>name1</i> <i>name2</i> ...)</tt> advises the compiler
|
|
that each <i>namej</i> is a valid but non-standard declaration name.
|
|
The purpose of this is to tell one compiler not to issue warnings
|
|
for declarations meant for another compiler or other program processor.
|
|
</dl>
|
|
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
This kind of declaration may be used only as a proclamation.
|
|
For example:
|
|
<P><pre>
|
|
(proclaim '(declaration author
|
|
target-language
|
|
target-machine))
|
|
|
|
(proclaim '(target-language ada))
|
|
|
|
(proclaim '(target-machine IBM-650))
|
|
</pre><P>
|
|
<P><pre>
|
|
(defun strangep (x)
|
|
(declare (author "Harry Tweeker"))
|
|
(member x '(strange weird odd peculiar)))
|
|
</pre><P>
|
|
</dl>
|
|
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
|
|
<p>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
|
|
<DL COMPACT>
|
|
<dd>
|
|
X3J13 voted in June 1989 (PROCLAIM-ETC-IN-COMPILE-FILE) <A NAME=9552> </A>
|
|
to introduce the new macro <tt>declaim</tt>, which is guaranteed
|
|
to be recognized appropriately by the compiler and is often more convenient
|
|
than <tt>proclaim</tt> for establishing global declarations.
|
|
<P>
|
|
The <tt>declaration</tt> declaration specifier may be used with <tt>declaim</tt>
|
|
as well as <tt>proclaim</tt>. The preceding examples would be better written
|
|
using <tt>declaim</tt>, to ensure that the compiler will process them properly.
|
|
<P>
|
|
<P><pre>
|
|
(declaim (declaration author
|
|
target-language
|
|
target-machine))
|
|
|
|
(declaim (target-language ada)
|
|
(target-machine IBM-650))
|
|
|
|
(defun strangep (x)
|
|
(declare (author "Harry Tweeker"))
|
|
(member x '(strange weird odd peculiar)))
|
|
</pre><P>
|
|
<P>
|
|
</DL>
|
|
<P>
|
|
X3J13 voted in March 1989 (DYNAMIC-EXTENT) <A NAME=9564> </A> to introduce a new
|
|
declaration specifier <tt>dynamic-extent</tt> for variables,
|
|
and voted in June 1989 (DYNAMIC-EXTENT-FUNCTION) <A NAME=9566> </A>
|
|
to extend it to handle function-names as well.
|
|
<DL COMPACT><DT><tt>dynamic-extent</tt>
|
|
<DD>
|
|
<P>
|
|
<tt>(dynamic-extent <i>item1</i> <i>item2</i> ... <i>itemn</i>)</tt>
|
|
declares that certain variables or function-names refer to data objects
|
|
whose extents may be regarded as dynamic; that is, the declaration
|
|
may be construed as a guarantee on the part of the programmer that
|
|
the program will behave correctly even if the data objects have only
|
|
dynamic extent rather than the usual indefinite extent.
|
|
<P>
|
|
Each <i>item</i> may be either a variable name or <tt>(function <i>f</i>)</tt>
|
|
where <i>f</i> is a function-name (see section <A HREF="node77.html#FUNCTIONNAMESECTION">7.1</A>).
|
|
(Of course, <tt>(function <i>f</i>)</tt> may be abbreviated in the usual way
|
|
as <tt>#'<i>f</i></tt>.)
|
|
<P>
|
|
It is permissible for an implementation simply to ignore this declaration.
|
|
In implementations that do not ignore it, the compiler (or interpreter)
|
|
is free to make whatever optimizations are appropriate given this
|
|
information; the most common optimization is to stack-allocate the
|
|
initial value of the object. The data types that can be optimized in this manner
|
|
may vary from implementation to implementation.
|
|
<P>
|
|
The meaning of this declaration can be stated more precisely.
|
|
We say that
|
|
object <i>x</i> is an <i>otherwise inaccessible part</i>
|
|
of <i>y</i> if and only if making <i>y</i> inaccessible would make <i>x</i> inaccessible.
|
|
(Note that every object is an otherwise inaccessible part of itself.)
|
|
Now suppose that construct <i>c</i> contains a <tt>dynamic-extent</tt> declaration for
|
|
variable (or function) <i>v</i> (which need not be bound by <i>c</i>). Consider the values
|
|
<IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap40641.gif"> taken on by <i>v</i> during the course of some execution of
|
|
<i>c</i>. The declaration asserts that if some object <i>x</i>
|
|
is an otherwise inaccessible part of <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap40645.gif">
|
|
whenever <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap40645.gif"> becomes the value of <i>v</i>,
|
|
then just after execution of
|
|
<b>c</b> terminates <i>x</i> will be either inaccessible or
|
|
still an otherwise inaccessible part of the value of <i>v</i>.
|
|
If this assertion is ever violated, the consequences are undefined.
|
|
<P>
|
|
In some implementations, it is
|
|
possible to allocate data structures in a way that will make them
|
|
easier to reclaim than by general-purpose garbage collection
|
|
(for example, on the stack or in some temporary area). The <tt>dynamic-extent</tt>
|
|
declaration is designed to give the implementation the information
|
|
necessary to exploit such techniques.
|
|
<P>
|
|
For example, in the code fragment
|
|
<P><pre>
|
|
(let ((x (list 'a1 'b1 'c1))
|
|
(y (cons 'a2 (cons 'b2 (cons 'c2 'd2)))))
|
|
(declare (dynamic-extent x y))
|
|
...)
|
|
</pre><P>
|
|
it is not difficult to prove that
|
|
the otherwise inaccessible parts of <tt>x</tt> include the three conses constructed by <tt>list</tt>,
|
|
and that the otherwise inaccessible parts of <tt>y</tt> include three other
|
|
conses manufactured by the three calls to <tt>cons</tt>.
|
|
Given the presence of the <tt>dynamic-extent</tt> declaration, a compiler would be
|
|
justified in stack-allocating these six conses and reclaiming their storage
|
|
on exit from the <tt>let</tt> form.
|
|
<P>
|
|
Since stack allocation of the initial value entails knowing at the
|
|
object's creation time that the object can be stack-allocated, it is
|
|
not generally useful to declare <tt>dynamic-extent</tt> for variables
|
|
that have no lexically apparent initial value. For example,
|
|
<P><pre>
|
|
(defun f ()
|
|
(let ((x (list 1 2 3)))
|
|
(declare (dynamic-extent x))
|
|
...))
|
|
</pre><P>
|
|
would permit a compiler to stack-allocate the
|
|
list in <tt>x</tt>. However,
|
|
<P><pre>
|
|
(defun g (x) (declare (dynamic-extent x)) ...)
|
|
(defun f () (g (list 1 2 3)))
|
|
</pre><P>
|
|
could not typically permit a similar optimization in <tt>f</tt> because of the
|
|
possibility of later redefinition of <tt>g</tt>.
|
|
Only an implementation careful enough to recompile <tt>f</tt>
|
|
if the definition of <tt>g</tt> were to change incompatibly could stack-allocate
|
|
the list argument to <tt>g</tt> in <tt>f</tt>.
|
|
<P>
|
|
Other interesting cases are
|
|
<P><pre>
|
|
(declaim (inline g))
|
|
(defun g (x) (declare (dynamic-extent x)) ...)
|
|
(defun f () (g (list 1 2 3)))
|
|
</pre><P>
|
|
and
|
|
<P><pre>
|
|
(defun f ()
|
|
(flet ((g (x) (declare (dynamic-extent x)) ...))
|
|
(g (list 1 2 3))))
|
|
</pre><P>
|
|
In each case some compilers might realize the optimization is possible and others
|
|
might not.
|
|
<P>
|
|
An interesting variant of this is the so-called <i>stack-allocated rest list</i>,
|
|
which can be achieved (in implementations supporting the optimization) by
|
|
<P><pre>
|
|
(defun f (&rest x)
|
|
(declare (dynamic-extent x))
|
|
...)
|
|
</pre><P>
|
|
Note here that although the initial value of <tt>x</tt> is not explicitly present,
|
|
nevertheless in the usual implementation strategy the
|
|
function <tt>f</tt> is responsible for assembling the list for <tt>x</tt> from the passed arguments,
|
|
so the <tt>f</tt> function can be optimized by a compiler to construct a
|
|
stack-allocated list instead of a heap-allocated list.
|
|
<P>
|
|
Some Common Lisp functions take other functions as arguments; frequently
|
|
the argument function is a so-called <i>downward funarg</i>, that is, a functional
|
|
argument that is passed only downward and whose extent may therefore be dynamic.
|
|
<P><pre>
|
|
(flet ((gd (x) (atan (sinh x))))
|
|
(declare (dynamic-extent #'gd)) ;<tt>mapcar</tt> won't hang on to <tt>gd</tt>
|
|
(mapcar #'gd my-list-of-numbers))
|
|
</pre><P>
|
|
<P>
|
|
The following three examples are in error, since in each case
|
|
the value of <tt>x</tt> is used outside of its
|
|
extent.
|
|
<P><pre>
|
|
(length (let ((x (list 1 2 3)))
|
|
(declare (dynamic-extent x))
|
|
x)) ;Wrong
|
|
</pre><P>
|
|
The preceding code is obviously incorrect, because the cons cells making
|
|
up the list in <tt>x</tt> might be deallocated (thanks to the declaration)
|
|
before <tt>length</tt> is called.
|
|
<P><pre>
|
|
(length (list (let ((x (list 1 2 3)))
|
|
(declare (dynamic-extent x))
|
|
x))) ;Wrong
|
|
</pre><P>
|
|
In this second case it is less obvious that
|
|
the code is incorrect, because one might argue that
|
|
the cons cells making
|
|
up the list in <tt>x</tt> have no effect on the result to be computed by <tt>length</tt>.
|
|
Nevertheless the code briefly violates the assertion implied by the declaration
|
|
and is therefore incorrect. (It is not difficult to imagine a perfectly
|
|
sensible implementation of a garbage collector that might become confused
|
|
by a cons cell containing a dangling pointer to a list that was once stack-allocated
|
|
but then deallocated.)
|
|
<P><pre>
|
|
(progn (let ((x (list 1 2 3)))
|
|
(declare (dynamic-extent x))
|
|
x) ;Wrong
|
|
(print "Six dollars is your change have a nice day NEXT!"))
|
|
</pre><P>
|
|
In this third case it is even less obvious that
|
|
the code is incorrect, because the value of <tt>x</tt>
|
|
returned from the <tt>let</tt> construct is discarded right away by the <tt>progn</tt>.
|
|
Indeed it is, but ``right away'' isn't fast enough.
|
|
The code briefly violates the assertion implied by the declaration
|
|
and is therefore incorrect. (If the code is being interpreted,
|
|
the interpreter might hang on to the value returned by the <tt>let</tt>
|
|
for some time before it is eventually discarded.)
|
|
<P>
|
|
Here is one last example, one that has little practical import but
|
|
is theoretically quite instructive.
|
|
<P><pre>
|
|
(dotimes (j 10)
|
|
(declare (dynamic-extent j))
|
|
(setq foo 3) ;Correct
|
|
(setq foo j)) ;Erroneous-but why? (see text)
|
|
</pre><P>
|
|
Since <tt>j</tt> is an integer by the
|
|
definition of <tt>dotimes</tt>, but <tt>eq</tt> and <tt>eql</tt> are not necessarily equivalent for
|
|
integers, what are the otherwise inaccessible parts of <tt>j</tt>, which this declaration
|
|
requires the body of the <tt>dotimes</tt> not to ``save''? If the value of <tt>j</tt> is <tt>3</tt>,
|
|
and the body does <tt>(setq foo 3)</tt>, is that an error? The answer is no, but
|
|
the interesting thing is that it depends on the implementation-dependent
|
|
behavior of <tt>eq</tt> on numbers. In an implementation where <tt>eq</tt> and <tt>eql</tt> are
|
|
equivalent for <tt>3</tt>, then <tt>3</tt> is not an otherwise inaccessible part because
|
|
<tt>(eq j (+ 2 1))</tt> is true,
|
|
and therefore there is another way to access the object besides
|
|
going through <tt>j</tt>. On the other hand, in an implementation where <tt>eq</tt> and
|
|
<tt>eql</tt> are not equivalent for <tt>3</tt>, then the particular <tt>3</tt> that is the value of
|
|
<tt>j</tt> is an otherwise inaccessible part, but any other <tt>3</tt> is not.
|
|
Thus <tt>(setq foo 3)</tt> is valid
|
|
but <tt>(setq foo j)</tt> is erroneous. Since <tt>(setq foo j)</tt> is erroneous in some
|
|
implementations, it is erroneous in all portable programs, but some other
|
|
implementations may not be able to detect the error. (If this conclusion seems
|
|
strange, it may help to replace <tt>3</tt> everywhere
|
|
in the preceding argument with some obvious
|
|
bignum such as <tt>375374638837424898243</tt> and to replace
|
|
<tt>10</tt> with some even larger bignum.)
|
|
<P>
|
|
The <tt>dynamic-extent</tt> declaration should be used with great care.
|
|
It makes possible great performance improvements in some situations, but
|
|
if the user misdeclares
|
|
something and consequently the implementation
|
|
returns a pointer into the stack (or stores it in the heap),
|
|
an undefined situation may result and the integrity of the Lisp storage
|
|
mechanism may be compromised. Debugging these situations may be tricky.
|
|
Users who have asked for this feature have indicated a willingness
|
|
to deal with such problems; nevertheless, I do not encourage
|
|
casual users to use this declaration.
|
|
</DL>
|
|
<img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<P>
|
|
An implementation is free to support other (implementation-dependent)
|
|
declaration specifiers as well.
|
|
On the other hand, a Common Lisp compiler is free to
|
|
ignore entire classes of declaration specifiers (for example,
|
|
implementation-dependent declaration specifiers
|
|
not supported by that compiler's
|
|
implementation), except for the <tt>declaration</tt> declaration specifier.
|
|
Compiler implementors are encouraged, however, to
|
|
program the compiler to issue by default a warning if the compiler finds
|
|
a declaration specifier of a kind it never uses. Such a warning is required
|
|
in any case
|
|
if a declaration specifier is not one of those defined above and has not been
|
|
declared in a <tt>declaration</tt> declaration.
|
|
<P>
|
|
<BR> <HR><A NAME=tex2html2831 HREF="node106.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html2829 HREF="node103.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html2823 HREF="node104.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html2833 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html2834 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
|
<B> Next:</B> <A NAME=tex2html2832 HREF="node106.html"> Type Declaration for </A>
|
|
<B>Up:</B> <A NAME=tex2html2830 HREF="node103.html"> Declarations</A>
|
|
<B> Previous:</B> <A NAME=tex2html2824 HREF="node104.html"> Declaration Syntax</A>
|
|
<HR> <P>
|
|
<HR>
|
|
<P><ADDRESS>
|
|
AI.Repository@cs.cmu.edu
|
|
</ADDRESS>
|
|
</BODY>
|