emacs.d/clones/lisp/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node105.html

789 lines
35 KiB
HTML
Raw Normal View History

2022-08-26 19:11:35 +02:00
<!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>&#160;</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.
(&lt; apples oranges)))
((or (complex apples)
(complex oranges))
(error &quot;Not yet implemented. Sorry.&quot;))
...))
</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 &quot;The Sound of Music&quot;)
(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 &quot;The Sound of Music&quot;)
(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>&#160;</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>&#160;</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>&#160;</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>&#160;</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>&#160;</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>&#160;</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>&#160;</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>&#160;</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>&#160;</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 &quot;Harry Tweeker&quot;))
(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>&#160;</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 &quot;Harry Tweeker&quot;))
(member x '(strange weird odd peculiar)))
</pre><P>
<P>
</DL>
<P>
X3J13 voted in March 1989 (DYNAMIC-EXTENT) <A NAME=9564>&#160;</A> to introduce a new
declaration specifier <tt>dynamic-extent</tt> for variables,
and voted in June 1989 (DYNAMIC-EXTENT-FUNCTION) <A NAME=9566>&#160;</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 (&amp;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 &quot;Six dollars is your change have a nice day NEXT!&quot;))
</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>