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

456 lines
24 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>8.5. Environments</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Environments">
<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=tex2html2792 HREF="node103.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html2790 HREF="node97.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html2786 HREF="node101.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html2794 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html2795 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html2793 HREF="node103.html"> Declarations</A>
<B>Up:</B> <A NAME=tex2html2791 HREF="node97.html"> Macros</A>
<B> Previous:</B> <A NAME=tex2html2787 HREF="node101.html"> Compiler Macros</A>
<HR> <P>
<H1><A NAME=SECTION001250000000000000000>8.5. Environments</A></H1>
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (SYNTACTIC-ENVIRONMENT-ACCESS) <A NAME=8713>&#160;</A> to add some facilities for obtaining information
from environment objects of the kind received as arguments
by macro expansion functions, <tt>*macroexpand-hook*</tt> functions,
and <tt>*evalhook*</tt> functions.
There is a minimal set of accessors <tt>(variable-information</tt>,
<tt>function-information</tt>, and <tt>declaration-information)</tt> and a constructor
<tt>(augment-environment)</tt> for environments.
<P>
All of the standard declaration specifiers, with the exception of <tt>special</tt>,
can be defined fairly easily using <tt>define-declaration</tt>. It also
seems to be able to handle most extended declarations.
<P>
The function <tt>parse-macro</tt> is provided so that
users don't have to write their
own code to destructure macro arguments.
This function is not entirely necessary since X3J13 voted
in March 1989 (DESTRUCTURING-BIND) <A NAME=8723>&#160;</A>
to add <tt>destructuring-bind</tt> to the language.
However, <tt>parse-macro</tt> is worth having anyway, since any program-analyzing
program is going to need to define it, and the implementation isn't completely
trivial even with <tt>destructuring-bind</tt> to build upon.
<P>
The function <tt>enclose</tt> allows expander functions to be defined in a non-null
lexical environment, as required by the vote of X3J13 in
March 1989 (DEFINING-MACROS-NON-TOP-LEVEL) <A NAME=8728>&#160;</A> . It
also provides a mechanism by which a program processing
the body of an <tt>(eval-when (:compile-toplevel) ...)</tt> form
can execute it in the enclosing environment (see issue
(EVAL-WHEN-NON-TOP-LEVEL) <A NAME=8730>&#160;</A> ).
<P>
In all of these functions the argument named <i>env</i> is an environment
object. (It is not required that implementations
provide a distinguished representation for such objects.) Optional <i>env</i>
arguments default to <tt>nil</tt>, which represents the local null lexical environment
(containing only global definitions and proclamations that are present in the
run-time environment). All of these functions should signal an error of type
<tt>type-error</tt> if the value of an environment argument is not a syntactic
environment object.
<P>
The accessor functions <tt>variable-information</tt>, <tt>function-information</tt>, and
<tt>declaration-information</tt> retrieve information about
declarations that are in
effect in the environment. Since implementations are permitted to ignore
declarations (except for <tt>special</tt> declarations and <tt>optimize safety</tt>
declarations if they ever compile unsafe code), these accessors are required
only to return information about declarations that were explicitly added to
the environment using <tt>augment-environment</tt>. They might also return
information about declarations recognized and added to the environment by the
interpreter or the compiler, but that is at the discretion of the
implementor. Implementations are also permitted to canonicalize
declarations, so the information returned by the accessors might not be
identical to the information that was passed to <tt>augment-environment</tt>.
<P>
<BR><b>[Function]</b><BR>
<tt>variable-information</tt> <tt><i>variable</i></tt> <tt>&amp;optional</tt> <tt><i>env</i></tt><P> This function returns information about the interpretation of the symbol
<i>variable</i> when it appears as a variable within the lexical environment <i>env</i>.
Three values are returned.
<P>
The first value indicates the type of definition or binding for <i>variable</i>
in <i>env</i>:
<DL COMPACT>
<DT><tt>nil</tt>
<DD>
There is no apparent definition or binding for <i>variable</i>.
<P>
<DT><tt>:special</tt>
<DD>
The <i>variable</i> refers to a special variable, either declared or proclaimed.
<P>
<DT><tt>:lexical</tt>
<DD>
The <i>variable</i> refers to a lexical variable.
<P>
<DT><tt>:symbol-macro</tt>
<DD>
The <i>variable</i> refers to a <tt>symbol-macrolet</tt> binding.
<P>
<DT><tt>:constant</tt>
<DD>
Either the <i>variable</i> refers to a named constant defined by
<tt>defconstant</tt> or the <i>variable</i> is a keyword symbol.
<P>
</DL>
<P>
The second value indicates whether there is a local binding of the name. If
the name is locally bound, the second value is true; otherwise, the second value
is <tt>nil</tt>.
<P>
The third value is an a-list containing information about declarations
that apply to the apparent binding of the <i>variable</i>. The keys in the a-list
are symbols that name declaration specifiers, and the format of the
corresponding value in the <i>cdr</i> of each pair depends on the particular
declaration name involved. The standard declaration names
that might appear as keys in this a-list are:
<DL COMPACT>
<DT><tt>dynamic-extent</tt>
<DD>
A non-<tt>nil</tt> value indicates that the <i>variable</i> has been
declared <tt>dynamic-extent</tt>. If the value is <tt>nil</tt>, the pair
might be omitted.
<P>
<DT><tt>ignore</tt>
<DD>
A non-<tt>nil</tt> value indicates that the <i>variable</i> has been declared
<tt>ignore</tt>. If the value is <tt>nil</tt>, the pair might be omitted.
<P>
<DT><tt>type</tt>
<DD>
The value is a type specifier associated with the <i>variable</i> by a <tt>type</tt>
declaration or an abbreviated declaration such as
<tt>(fixnum <i>variable</i>)</tt>.
If no explicit association exists, either by <tt>proclaim</tt> or
<tt>declare</tt>, then the type specifier is <tt>t</tt>. It is permissible for
implementations to use a type specifier that is equivalent
to or a supertype of the one appearing in the original
declaration. If the value is <tt>t</tt>, the pair might be
omitted.
<P>
</DL>
If an implementation supports additional declaration specifiers that
apply to variable bindings, those declaration names might also
appear in the a-list. However, the corresponding key must not
be a symbol that is external in any package defined in the standard
or that is otherwise accessible in the <tt>common-lisp-user</tt> package.
<P>
The a-list might contain multiple entries for a given key.
The consequences of destructively modifying the list
structure of this a-list or its elements (except for values that
appear in the a-list as a result of <tt>define-declaration</tt>) are undefined.
<P>
Note that the global binding might differ from the
local one and can be retrieved by calling <tt>variable-information</tt>
with a null lexical environment.
<P>
<BR><b>[Function]</b><BR>
<tt>function-information</tt> <tt><i>function</i></tt> <tt>&amp;optional</tt> <tt><i>env</i></tt><P> This function returns information about the interpretation of the function-name
<i>function</i> when it appears in a functional position within lexical
environment <i>env</i>. Three values are returned.
<P>
The first value indicates the type of definition or binding of the function-name
which is apparent in <i>env</i>:
<DL COMPACT>
<DT><tt>nil</tt>
<DD> There is no apparent definition for <i>function</i>.
<P>
<DT><tt>:function</tt>
<DD> The <i>function</i> refers to a function.
<P>
<DT><tt>:macro</tt>
<DD> The <i>function</i> refers to a macro.
<P>
<DT><tt>:special-form</tt>
<DD> The <i>function</i> refers to a special form.
<P>
</DL>
Some function-names can refer to both a global macro and a global special
form. In such a case the macro takes precedence and <tt>:macro</tt> is returned as
the first value.
<P>
The second value specifies whether the definition is local or global. If
local, the second value is true; it is <tt>nil</tt> when the definition is
global.
<P>
The third value is an a-list containing information about declarations
that apply to the apparent binding of the function. The keys in the a-list
are symbols that name declaration specifiers, and the format of the
corresponding values in the <i>cdr</i> of each pair depends on the particular
declaration name involved. The standard declaration names
that might appear as keys in this a-list are:
<DL COMPACT>
<DT><tt>dynamic-extent</tt>
<DD>
A non-<tt>nil</tt> value indicates that the function has been
declared <tt>dynamic-extent</tt>. If the value is <tt>nil</tt>, the pair
might be omitted.
<P>
<DT><tt>inline</tt>
<DD>
The value is one of the symbols <tt>inline</tt>, <tt>notinline</tt>, or <tt>nil</tt> to indicate
whether the function-name has been declared <tt>inline</tt>,
declared <tt>notinline</tt>, or neither, respectively.
If the value is <tt>nil</tt>, the pair might be omitted.
<P>
<DT><tt>ftype</tt>
<DD>
The value is the type specifier associated with the function-name in the
environment, or the symbol <tt>function</tt> if there is no functional
type declaration or proclamation associated with the function-name.
This value might not include all the apparent <tt>ftype</tt>
declarations for the function-name. It is permissible for
implementations to use a type specifier that is equivalent
to or a supertype of the one that appeared in the original
declaration. If the value is <tt>function</tt>, the pair might be
omitted.
<P>
</DL>
If an implementation supports additional declaration specifiers that
apply to function bindings, those declaration names might also
appear in the a-list. However, the corresponding key must not be
a symbol that is external in any package defined in the standard or
that is otherwise accessible in the <tt>common-lisp-user</tt> package.
<P>
The a-list might contain multiple entries for a given key.
In this case the value associated with the first entry has
precedence. The consequences of destructively modifying the list
structure of this a-list or its elements (except for values
that appear in the a-list as a result of <tt>define-declaration</tt>) are
undefined.
<P>
Note that the global binding might differ from the local
one and can be retrieved by calling <tt>function-information</tt> with a null
lexical environment.
<P>
<BR><b>[Function]</b><BR>
<tt>declaration-information</tt> <tt><i>decl-name</i></tt> <tt>&amp;optional</tt> <tt><i>env</i></tt><P> This function returns information about declarations named by the
symbol <i>decl-name</i> that are in force in the environment <i>env</i>.
Only declarations that do not apply to function or variable bindings
can be accessed with this function. The format of the information
that is returned depends on the <i>decl-name</i> involved.
<P>
It is required that this function recognize <tt>optimize</tt> and <tt>declaration</tt> as
<i>decl-name</i>s. The values returned for these two cases are as follows:
<DL COMPACT>
<DT><tt>optimize</tt>
<DD>
A single value is returned,
a list whose entries are of the form <tt>(<i>quality</i> <i>value</i>)</tt>, where
<i>quality</i> is one of the standard optimization qualities
<tt>(speed</tt>, <tt>safety</tt>, <tt>compilation-speed</tt>, <tt>space</tt>, <tt>debug)</tt>
or some implementation-specific optimization quality, and
<i>value</i> is an integer in the range 0 to 3 (inclusive).
The returned list
always contains an entry for each of the standard qualities and
for each of the implementation-specific qualities. In the
absence of any previous declarations, the associated values are
implementation-dependent. The list might contain multiple
entries for a quality, in which case the first such entry
specifies the current value.
The consequences of destructively modifying this list or
its elements are undefined.
<P>
<DT><tt>declaration</tt>
<DD>
A single value is returned,
a list of the declaration names that have been proclaimed as
valid through the use of the <tt>declaration</tt> proclamation.
The consequences of destructively modifying this list or
its elements are undefined.
<P>
</DL>
If an implementation is extended to recognize additional
declaration specifiers in <tt>declare</tt> or <tt>proclaim</tt>, it is required that
either the <tt>declaration-information</tt> function should recognize those
declarations also or the implementation should provide a similar accessor that is
specialized for that declaration specifier. If <tt>declaration-information</tt>
is used to return the information, the corresponding <i>decl-name</i> must not
be a symbol that is external in any package defined in the standard or
that is otherwise accessible in the <tt>common-lisp-user</tt> package.
<P>
<BR><b>[Function]</b><BR>
<pre>
augment-environment <i>env</i> &amp;key :variable :symbol-macro
:function :macro :declare
</pre>
<P> This function returns a new environment containing the information present in
<i>env</i> augmented with the information provided by the keyword arguments. It is
intended to be used by program analyzers that perform a code walk.
<P>
The arguments are supplied as follows.
<DL COMPACT><DT><tt>:variable</tt>
<DD>
The argument is a list of symbols that will be visible as bound variables in
the new environment. Whether each binding is to be interpreted
as special or lexical depends on <tt>special</tt> declarations recorded
in the environment or provided in the <tt>:declare</tt> argument.
<P>
<DT><tt>:symbol-macro</tt>
<DD>
The argument is a list of symbol macro definitions, each of the form
<tt>(<i>name</i> <i>definition</i>)</tt>; that is, the argument is
in the same format as the
<i>cadr</i> of a <tt>symbol-macrolet</tt> special form. The new environment
will have local symbol-macro bindings of each symbol to the
corresponding expansion, so that <tt>macroexpand</tt> will be able to
expand them properly. A type declaration in the <tt>:declare</tt>
argument that refers to a name in this list implicitly
modifies the definition associated with the name. The effect
is to wrap a <tt>the</tt> form mentioning the type around the
definition.
<P>
<DT><tt>:function</tt>
<DD>
The argument is a list of function-names that will be visible as local
function bindings in the new environment.
<P>
<DT><tt>:macro</tt>
<DD>
The argument is a list of local macro definitions,
each of the form <tt>(<i>name</i> <i>definition</i>)</tt>.
Note that the argument is <i>not</i>
in the same format as the
<i>cadr</i> of a <tt>macrolet</tt> special form.
Each <i>definition</i> must be a function of two
arguments (a form and an environment). The new environment
will have local macro bindings of each name to the
corresponding expander function, which will be returned by
<tt>macro-function</tt> and used by <tt>macroexpand</tt>.
<P>
<DT><tt>:declare</tt>
<DD>
The argument is a list of declaration specifiers.
Information about these declarations can
be retrieved from the resulting environment using
<tt>variable-information</tt>, <tt>function-information</tt>, and
<tt>declaration-information</tt>.
<P>
</DL>
The consequences of subsequently
destructively modifying the list
structure of any of the arguments to this function are undefined.
<P>
An error is signaled if any of the symbols naming a symbol macro in the
<tt>:symbol-macro</tt> argument is also included in the <tt>:variable</tt> argument.
An error is
signaled if any symbol naming a symbol macro in the <tt>:symbol-macro</tt> argument is
also included in a <tt>special</tt> declaration specifier in the <tt>:declare</tt> argument.
An error is
signaled if any symbol naming a macro in the <tt>:macro</tt> argument is also included
in the <tt>:function</tt> argument.
The condition type of each of these errors is <tt>program-error</tt>.
<P>
The extent of the returned environment is the same as the extent of the
argument environment <i>env</i>. The result might share structure with <i>env</i>
but <i>env</i> is not modified.
<P>
While an environment argument received by an <tt>*evalhook*</tt>
function is permitted to be used as the
environment argument to <tt>augment-environment</tt>, the consequences are undefined if an
attempt is made to use the result of <tt>augment-environment</tt> as the environment
argument for <tt>evalhook</tt>. The environment
returned by <tt>augment-environment</tt> can be used only for syntactic analysis, that is,
as an argument to
the functions defined in this section and functions such as <tt>macroexpand</tt>.
<P>
<BR><b>[Macro]</b><BR>
<tt>define-declaration</tt> <tt><i>decl-name</i></tt> <tt><i>lambda-list</i></tt> <tt>{<i>form</i>}*</tt><P> This macro defines a handler for the named declaration. It is the mechanism by which
<tt>augment-environment</tt> is extended to support additional declaration
specifiers. The function defined by this macro will be called with two
arguments, a declaration specifier whose <i>car</i> is <i>decl-name</i>
and the <i>env</i> argument to
<tt>augment-environment</tt>. This function must return two values. The
first value must be one of the following keywords:
<DL COMPACT>
<DT><tt>:variable</tt>
<DD> The declaration applies to variable bindings.
<DT><tt>:function</tt>
<DD> The declaration applies to function bindings.
<DT><tt>:declare</tt>
<DD> The declaration does not apply to bindings.
<P>
</DL>
If the first value is <tt>:variable</tt> or <tt>:function</tt>
then the second value must be a list, the elements of which are lists of the
form <tt>(<i>binding-name</i> <i>key</i> <i>value</i>)</tt>. If the corresponding information
function (either <tt>variable-information</tt> or <tt>function-information</tt>) is applied to
the <i>binding-name</i> and the augmented environment, the a-list returned
by the information function as its third value will contain the <i>value</i>
under the specified <i>key</i>.
<P>
If the first value is <tt>:declare</tt>, the second value must be a cons
of the form <tt>(<i>key</i> . <i>value</i>)</tt>. The function
<tt>declaration-information</tt> will return <i>value</i> when applied to the
<i>key</i> and the augmented environment.
<P>
<tt>define-declaration</tt> causes <i>decl-name</i> to be proclaimed to be a
declaration; it is as if its expansion included a call <tt>(proclaim
'(declaration <i>decl-name</i>))</tt>. As is the case with standard
declaration specifiers, the evaluator and compiler are permitted,
but not required, to add information about declaration specifiers
defined with <tt>define-declaration</tt> to the macro expansion and <tt>*evalhook*</tt>
environments.
<P>
The consequences are undefined if <i>decl-name</i> is a symbol that can
appear as the <i>car</i> of any standard declaration specifier.
<P>
The consequences are also undefined if the return value from a
declaration handler defined with <tt>define-declaration</tt> includes a <i>key</i> name
that is used by the corresponding accessor to return information about
any standard declaration specifier. (For example, if
the first return value from the handler is <tt>:variable</tt>, the second return
value may not use the symbols <tt>dynamic-extent</tt>, <tt>ignore</tt>, or <tt>type</tt>
as <i>key</i> names.)
<P>
The <tt>define-declaration</tt> macro does not have any special compile-time
side effects (see section <A HREF="node224.html#COMPILERSECTION">25.1</A>).
<P>
<BR><b>[Function]</b><BR>
<tt>parse-macro <i>name</i> <i>lambda-list</i> <i>body</i> &amp;optional <i>env</i></tt><P> This function is used to process a macro definition in the same way
as <tt>defmacro</tt> and <tt>macrolet</tt>. It returns a lambda-expression that accepts
two arguments, a form and an environment. The <i>name</i>, <i>lambda-list</i>,
and <i>body</i> arguments correspond to the parts of a <tt>defmacro</tt> or <tt>macrolet</tt>
definition.
<P>
The <i>lambda-list</i> argument may include <tt>&amp;environment</tt> and <tt>&amp;whole</tt>
and may include destructuring.
The <i>name</i>
argument is used to enclose the <i>body</i> in an implicit <tt>block</tt> and might also
be used for implementation-dependent purposes (such as including the name of
the macro in error messages if the form does not match the <i>lambda-list</i>).
<P>
<BR><b>[Function]</b><BR>
<tt>enclose <i>lambda-expression</i> &amp;optional <i>env</i></tt><P> This function returns an object of type <tt>function</tt> that is equivalent to what
would be obtained by evaluating <tt>`(function ,<i>lambda-expression</i>)</tt>
in a syntactic
environment <i>env</i>. The <i>lambda-expression</i> is permitted to reference only the
parts of the environment argument <i>env</i> that are relevant only to syntactic
processing, specifically declarations and the definitions of macros and
symbol macros. The consequences are undefined if the <i>lambda-expression</i>
contains any references to variable or function bindings that are
lexically visible in <i>env</i>, any <tt>go</tt> to a tag that is lexically visible in
<i>env</i>, or any <tt>return-from</tt> mentioning a block name that is lexically
visible in <i>env</i>.
<P>
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR> <HR><A NAME=tex2html2792 HREF="node103.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html2790 HREF="node97.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html2786 HREF="node101.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html2794 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html2795 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html2793 HREF="node103.html"> Declarations</A>
<B>Up:</B> <A NAME=tex2html2791 HREF="node97.html"> Macros</A>
<B> Previous:</B> <A NAME=tex2html2787 HREF="node101.html"> Compiler Macros</A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>