emacs.d/clones/lisp/HyperSpec-7-0/HyperSpec/Issues/iss342_w.htm
2023-01-18 20:30:47 +01:00

631 lines
43 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Issue SYNTACTIC-ENVIRONMENT-ACCESS Writeup</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="../Issues/iss341_w.htm">
<LINK REL=UP HREF="../Issues/iss342.htm">
<LINK REL=NEXT HREF="../Issues/iss343_w.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss341_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss342.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss343_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue SYNTACTIC-ENVIRONMENT-ACCESS Writeup</H2>
<PRE><B>Forum:</B> Compiler<P>
<B>Issue:</B> <A HREF="iss342.htm">SYNTACTIC-ENVIRONMENT-ACCESS</A><P>
<B>References:</B> CLtL Chapter 8: Macros,<P>
CLtL Chapter 9: Declarations,<P>
Issue COMPILE-FILE-ENVIRONMENT,<P>
Issue <A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL</A>,<P>
Issue <A REL=DEFINITION HREF="../Body/m_destru.htm#destructuring-bind"><B>DESTRUCTURING-BIND</B></A>,<P>
Issue <A HREF="iss147.htm">EVAL-WHEN-NON-TOP-LEVEL</A>,<P>
Issue <A HREF="iss185.htm">GET-SETF-METHOD-ENVIRONMENT</A>,<P>
Issue <A HREF="iss174.htm">FUNCTION-NAME</A>,<P>
Issue <A HREF="iss175_m.htm">FUNCTION-TYPE</A>,<P>
Issue <A HREF="iss229.htm">MACRO-ENVIRONMENT-EXTENT</A>,<P>
Issue <A HREF="iss230_m.htm">MACRO-FUNCTION-ENVIRONMENT</A>,<P>
Issue PROCLAIM-LEXICAL,<P>
Issue <A HREF="iss252.htm">PACKAGE-CLUTTER</A><P>
<B>Category:</B> ADDITION<P>
<B>Edit history:</B> Version 1, 2-Oct-88, Eric Benson<P>
Version 2, 17-Feb-89, Kim A. Barrett<P>
Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)<P>
Version 4, 12-Mar-89, Sandra Loosemore (more revisions)<P>
Version 5, 20-Mar-89, Sandra Loosemore (only proposal SMALL)<P>
Version 6, 23-Mar-89, Sandra Loosemore (more revisions)<P>
Version 7, 7-Apr-89, Moon &amp; Barrett (more revisions)<P>
Version 8, 9-Jun-89, Kim A. Barrett (add DEFDECLARE)<P>
Version 9, 13-Jun-89, Moon (small corrections)<P>
Version 10, 22-Jun-89, Loosemore (more clarifications,<P>
primarily relating to DEFDECLARE)<P>
Version 11, 04-Jul-89, Loosemore (amendments from June mtg)<P>
<P>
<B>Status:</B> Proposal SMALL passed June 89<P>
<P>
<P>
<B>Problem description:<P>
</B><P>
When macro forms are expanded, the expansion function is called with two<P>
arguments: the form to be expanded, and the environment in which the form was<P>
found. The environment argument is of limited utility. The only use<P>
sanctioned currently is as an argument to <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A> or <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand-1"><B>MACROEXPAND-1</B></A> or<P>
passed directly as an argument to another macro expansion function. Recently<P>
passed cleanup issues allow it as an argument to <A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A> and to<P>
GET-SETF-METHOD.<P>
<P>
It is very difficult to write a code walker that can correctly handle local<P>
macro and function definitions, due to insufficient access to the information<P>
contained in environments and the inability to augment environments with local<P>
definitions.<P>
<P>
<P>
<B>Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):<P>
</B><P>
The following functions <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> information about syntactic environment<P>
objects. In all of these functions the argument named ENV is an environment<P>
of the sort received by the <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;ENVIRONMENT</B></A> argument to a macro or as the<P>
environment argument for EVALHOOK. (It is not required that implementations<P>
<A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> a distinguished representation for such objects.) Optional &quot;env&quot;<P>
arguments default to <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, which represents the local null lexical environment<P>
(containing only global definitions <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> proclamations that are present in <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A><P>
runtime environment). All of these functions should signal an error of type<P>
<A REL=DEFINITION HREF="../Body/e_tp_err.htm#type-error"><B>TYPE-ERROR</B></A> if the value of an environment argument is not a syntactic<P>
environment.<P>
<P>
The accessors VARIABLE-INFORMATION, FUNCTION-INFORMATION, and<P>
DECLARATION-INFORMATION retrieve information about declarations that are in<P>
effect in the environment. Since implementations are permitted to ignore<P>
declarations (except for <A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> declarations and <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A><P>
declarations if they ever compile unsafe code), these accessors are required<P>
only to return information about declarations that were explicitly added to<P>
the environment using AUGMENT-ENVIRONMENT. They might also return<P>
information about declarations recognized and added to the environment by the<P>
interpreter or the compiler, but that is optional at the discretion of the<P>
implementer. Implementations are also permitted to canonicalize<P>
declarations, so the information returned by the accessors might not be<P>
identical to the information that was passed to AUGMENT-ENVIRONMENT.<P>
<P>
VARIABLE-INFORMATION variable &amp;optional env [Function]<P>
<P>
This function returns information about the interpretation of the symbol<P>
<A REL=DEFINITION HREF="../Body/f_docume.htm#variable"><B>VARIABLE</B></A> when it appears as a variable within the lexical environment ENV.<P>
The following three values are returned.<P>
<P>
The first value indicates the type of definition or binding which is apparent<P>
in ENV:<P>
<P>
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> There is no apparent definition or binding for variable.<P>
<P>
:SPECIAL <A REL=DEFINITION HREF="../Body/f_docume.htm#variable"><B>VARIABLE</B></A> refers to a special variable, either declared <P>
or proclaimed. <P>
<P>
:LEXICAL <A REL=DEFINITION HREF="../Body/f_docume.htm#variable"><B>VARIABLE</B></A> refers to a lexical variable.<P>
<P>
:SYMBOL-MACRO <A REL=DEFINITION HREF="../Body/f_docume.htm#variable"><B>VARIABLE</B></A> refers to a <A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>SYMBOL-MACROLET</B></A> binding.<P>
<P>
:CONSTANT <A REL=DEFINITION HREF="../Body/f_docume.htm#variable"><B>VARIABLE</B></A> refers to a named constant, defined by<P>
<A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A>, or <A REL=DEFINITION HREF="../Body/f_docume.htm#variable"><B>VARIABLE</B></A> is a keyword symbol.<P>
<P>
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result will also<P>
refer to variables proclaimed lexical.]<P>
<P>
The second value indicates whether there is a local binding of the name. If<P>
the name is locally bound, the second value is true. Otherwise, <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> is<P>
returned.<P>
<P>
The third value is an a-list containing information about declarations<P>
that apply to the apparent binding of the variable. The keys in the a-list<P>
are symbols which name declaration-specifiers, and the format of the<P>
corresponding value in the <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> of each pair depends on the particular <P>
declaration name involved. The <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> declaration names<P>
that might appear as keys in this a-list are:<P>
<P>
<A REL=DEFINITION HREF="../Body/d_dynami.htm#dynamic-extent"><B>DYNAMIC-EXTENT</B></A> a non-NIL value indicates that the variable has been<P>
declared <A REL=DEFINITION HREF="../Body/d_dynami.htm#dynamic-extent"><B>DYNAMIC-EXTENT</B></A>. If the value is <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, the pair<P>
might be omitted.<P>
<P>
<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> a non-NIL value indicates that the variable has been declared<P>
<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>. If the value is <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, the pair might be omitted.<P>
<P>
<A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>TYPE</B></A> a type specifier associated with the variable by a <A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>TYPE</B></A><P>
declaration or an abbreviated declaration such as (<A REL=DEFINITION HREF="../Body/t_fixnum.htm#fixnum"><B>FIXNUM</B></A> VAR).<P>
If no explicit association exists, either by <A REL=DEFINITION HREF="../Body/f_procla.htm#proclaim"><B>PROCLAIM</B></A> or<P>
<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A>, then the type specifier is T. It is permissible for<P>
implementations to use a type specifier that is equivalent<P>
to or a supertype of the one appearing in the original<P>
declaration. If the value is T, the pair might be<P>
omitted.<P>
<P>
If an implementation supports additional declaration-specifiers that<P>
apply to variable bindings, those declaration names might also<P>
appear in the a-list. However, the corresponding key must not<P>
be a symbol that is external in any package defined in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A><P>
or that is otherwise accessible in the USER package.<P>
<P>
The a-list might contain multiple entries for a given key.<P>
The consequences of destructively modifying the list<P>
<A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A> of this a-list or its elements (except for values that <P>
appear in the a-list as a result of DEFINE-DECLARATION) are undefined.<P>
<P>
Programmers are reminded that the global binding might differ from the<P>
local one, and can be retrieved by calling VARIABLE-INFORMATION<P>
again with a null lexical environment.<P>
<P>
<P>
FUNCTION-INFORMATION function &amp;optional env [Function]<P>
<P>
This function returns information about the interpretation of the function<P>
name <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> when it appears in a functional position within lexical <P>
environment ENV. The following three values are returned.<P>
<P>
The first value indicates the type of definition or binding of the function<P>
name which is apparent in ENV:<P>
<P>
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> There is no apparent definition for <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A>.<P>
<P>
:FUNCTION <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> refers to a function.<P>
<P>
:MACRO <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> refers to a macro.<P>
<P>
:SPECIAL-FORM <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> refers to a special form.<P>
<P>
Some function names can refer to both a global macro and a global special<P>
form. In such a case, the macro takes precedence, and :MACRO is returned as<P>
the first value.<P>
<P>
The second value specifies whether the definition is local or global. If<P>
local, the second value is true, and it is false when the definition is<P>
global.<P>
<P>
The third value is an a-list containing information about declarations<P>
that apply to the apparent binding of the function. The keys in the a-list<P>
are symbols which name declaration-specifiers, and the format of the<P>
corresponding values in the <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> of each pair depends on the particular <P>
declaration name involved. The <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> declaration names<P>
that might appear as keys in this a-list are:<P>
<P>
<A REL=DEFINITION HREF="../Body/d_inline.htm#inline"><B>INLINE</B></A> one of the symbols <A REL=DEFINITION HREF="../Body/d_inline.htm#inline"><B>INLINE</B></A>, <A REL=DEFINITION HREF="../Body/d_inline.htm#notinline"><B>NOTINLINE</B></A>, or <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> to indicate<P>
whether the function name has been declared <A REL=DEFINITION HREF="../Body/d_inline.htm#inline"><B>INLINE</B></A>, has been<P>
declared <A REL=DEFINITION HREF="../Body/d_inline.htm#notinline"><B>NOTINLINE</B></A>, or neither. If the value is <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, the<P>
pair might be omitted.<P>
<P>
<A REL=DEFINITION HREF="../Body/d_ftype.htm#ftype"><B>FTYPE</B></A> the type specifier associated with the function name in the<P>
environment, or the symbol <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> if there is no functional<P>
type declaration or proclamation associated with the function<P>
name. This value might not include all the apparent <A REL=DEFINITION HREF="../Body/d_ftype.htm#ftype"><B>FTYPE</B></A><P>
declarations for the function name. It is permissible for<P>
implementations to use a type specifier that is equivalent<P>
to or a supertype of the one that appeared in the original<P>
declaration. If the value is <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A>, the pair might be<P>
omitted. <P>
<P>
<A REL=DEFINITION HREF="../Body/d_dynami.htm#dynamic-extent"><B>DYNAMIC-EXTENT</B></A> a non-NIL value indicates that the function has been<P>
declared <A REL=DEFINITION HREF="../Body/d_dynami.htm#dynamic-extent"><B>DYNAMIC-EXTENT</B></A>. If the value is <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, thie pair<P>
might be omitted.<P>
<P>
If an implementation supports additional declaration-specifiers that<P>
apply to function bindings, those declaration names might also<P>
appear in the a-list. However, the corresponding key must not be<P>
a symbol that is external in any package defined in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> or<P>
that is otherwise accessible in the USER package.<P>
<P>
The a-list might contain multiple entries for a given key.<P>
In this case the value associated with the first entry has<P>
precedence. The consequences of destructively modifying the list<P>
<A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A> of this a-list or its elements (except for values<P>
that appear in the a-list as a result of DEFINE-DECLARATION) are <P>
undefined.<P>
<P>
Programmers are reminded that the global binding might differ from the local<P>
one, and can be retrieved by calling FUNCTION-INFORMATION again with a null<P>
lexical environment.<P>
<P>
<P>
DECLARATION-INFORMATION decl-name &amp;optional env [Function]<P>
<P>
This function returns information about declarations named by the<P>
symbol DECL-NAME that are in force in the environment ENV.<P>
Only declarations that do not apply to function or variable bindings<P>
can be accessed with this function. The format of the information<P>
that is returned depends on the DECL-NAME involved.<P>
<P>
It is required that this function recognize <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> and <A REL=DEFINITION HREF="../Body/d_declar.htm#declaration"><B>DECLARATION</B></A> as<P>
DECL-NAMEs. The values returned for these two cases are as follows:<P>
<P>
<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> a list whose entries are of the form (quality value), where<P>
&quot;quality&quot; is one of the optimization qualities defined by the<P>
<A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A>, <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A>, <A REL=DEFINITION HREF="../Body/d_optimi.htm#compilation-speed"><B>COMPILATION-SPEED</B></A>, <A REL=DEFINITION HREF="../Body/d_optimi.htm#space"><B>SPACE</B></A>, and <A REL=DEFINITION HREF="../Body/d_optimi.htm#debug"><B>DEBUG</B></A>)<P>
or some implementation-specific optimization quality, and<P>
&quot;value&quot; is an integer in the range 0 to 3. The returned list<P>
always contains an entry for each of the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> qualities and<P>
for each of the implementation-specific qualities. In the<P>
absence of any previous declarations, the associated values are<P>
implementation-dependent. The list might contain multiple<P>
entries for a quality, in which case the first such entry<P>
specifies the current value.<P>
The consequences of destructively modifying this list or<P>
its elements are undefined.<P>
<P>
<P>
<A REL=DEFINITION HREF="../Body/d_declar.htm#declaration"><B>DECLARATION</B></A> a list of the declaration names which have been proclaimed as<P>
valid through the use of the <A REL=DEFINITION HREF="../Body/d_declar.htm#declaration"><B>DECLARATION</B></A> proclamation.<P>
The consequences of destructively modifying this list or<P>
its elements are undefined.<P>
<P>
If an implementation has been extended to recognize additional<P>
declaration specifiers in <A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> or <A REL=DEFINITION HREF="../Body/f_procla.htm#proclaim"><B>PROCLAIM</B></A>, it is required that<P>
either the DECLARATION-INFORMATION function should also recognize those<P>
declarations, or that the implementation <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> an accessor that is<P>
specialized for that declaration specifier. If DECLARATION-INFORMATION<P>
is used to return the information, the corresponding DECL-NAME must not<P>
be a symbol that is external in any package defined in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> or<P>
that is otherwise accessible in the USER package.<P>
<P>
<P>
AUGMENT-ENVIRONMENT env <A REL=DEFINITION HREF="../Body/03_da.htm#AMkey"><B>&amp;KEY</B></A> variable<P>
symbol-macro<P>
function<P>
macro<P>
declare [Function]<P>
<P>
This function returns a new environment containing the information present in<P>
ENV, augmented with the information provided by the keyword arguments. It is<P>
intended to be used by program analyzers that perform a code walk.<P>
<P>
The arguments are supplied as follows:<P>
<P>
:VARIABLE A list of symbols which shall be visible as bound variables in<P>
the new environment. Whether each binding is to be interpreted<P>
as special or lexical depends on <A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> declarations recorded<P>
in the environment or provided in the :DECLARE argument list.<P>
<P>
:SYMBOL-MACRO A list of symbol macro definitions, specified as a list of<P>
(name definition) lists (that is, in the same format as the<P>
<A REL=DEFINITION HREF="../Body/f_car_c.htm#cadr"><B>CADR</B></A> of a <A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>SYMBOL-MACROLET</B></A> special form). The new environment<P>
will have local symbol-macro bindings of each symbol to the<P>
corresponding expansion, so that <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A> will be able to<P>
expand them properly. A type declaration in the :DECLARE<P>
argument which refers to a name in this list implicitly<P>
modifies the definition associated with the name. The effect<P>
is to wrap a <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>THE</B></A> form mentioning the type around the<P>
definition.<P>
<P>
:FUNCTION A list of function names which shall be visible as local<P>
function bindings in the new environment.<P>
<P>
:MACRO A list of local macro definitions, specified as a list of (name<P>
definition) lists. Each definition must be a function of two<P>
arguments (a form and an environment). The new environment<P>
will have local macro bindings of each name to the<P>
corresponding expander function, which will be returned by<P>
<A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A> and used by <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A>.<P>
<P>
:DECLARE A list of decl-specs. Information about these declarations can<P>
be retrieved from the resulting environment using the<P>
VARIABLE-INFORMATION, FUNCTION-INFORMATION, and<P>
DECLARATION-INFORMATION accessors.<P>
<P>
An error is signalled if any of the symbols naming macros in the<P>
:SYMBOL-MACRO alist are also included in the :VARIABLE list. An error is<P>
signaled if any of the symbols naming macros in the :SYMBOL-MACRO alist are<P>
also included in a <A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> decl-spec in the :DECLARE argument. An error is<P>
signalled if any of the names of macros in the :MACRO alist are also included<P>
in the :FUNCTION list. The consequences of destructively modifying the list<P>
<A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A> of any of the arguments to this function are undefined.<P>
<P>
The condition type of each of these errors is <A REL=DEFINITION HREF="../Body/e_progra.htm#program-error"><B>PROGRAM-ERROR</B></A>.<P>
<P>
The extent of the returned environment is the same as the extent of the<P>
argument environment. The result might share <A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A> with the argument<P>
environment, but the argument environment is not modified.<P>
<P>
While an environment argument from EVALHOOK is permitted to be used as the<P>
environment argument for this function, the reverse is not true. If an<P>
attempt is made to use the result of AUGMENT-ENVIRONMENT as the environment<P>
argument for EVALHOOK, the consequences are undefined. The environment<P>
returned by AUGMENT-ENVIRONMENT can only be used for syntactic analysis, ie.<P>
the functions specified by this proposal and functions such as <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A>.<P>
<P>
<P>
DEFINE-DECLARATION decl-name lambda-list &amp;body body [Macro]<P>
<P>
Define a handler for the named declaration. This is the mechanism by which<P>
AUGMENT-ENVIRONMENT is extended to support additional declaration<P>
specifiers. The function defined by this macro will be called with two<P>
arguments, a decl-spec whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> is decl-name, and the ENV argument to<P>
AUGMENT-ENVIRONMENT. Two values must be returned by the function. The<P>
first value must be one of the following keywords:<P>
<P>
:VARIABLE the declaration applies to variable bindings.<P>
:FUNCTION the declaration applies to function bindings.<P>
:DECLARE the declaration does not apply to bindings.<P>
<P>
For the case where the first value indicates the declaration applies to<P>
bindings, the second value is a list, the elements of which are lists of the<P>
form (binding-name key value). If the corresponding information<P>
function (either VARIABLE-INFORMATION or FUNCTION-INFORMATION) is applied to<P>
the binding name and the augmented environment, the a-list which is<P>
the third value returned by the information function will contain the value<P>
under the specified key.<P>
<P>
When the first value is :DECLARE, the second value is a cons whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> is a<P>
key and whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> is the associated value. The function<P>
DECLARATION-INFORMATION, when applied to the key and the augmented<P>
environment, will return the associated value.<P>
<P>
DEFINE-DECLARATION causes DECL-NAME to be proclaimed to be a<P>
declaration (it is as if its expansion included a call (<A REL=DEFINITION HREF="../Body/f_procla.htm#proclaim"><B>PROCLAIM</B></A><P>
'(<A REL=DEFINITION HREF="../Body/d_declar.htm#declaration"><B>DECLARATION</B></A> decl-name))). As is the case with <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A><P>
declaration specifiers, the evaluator and compiler are permitted,<P>
but not required, to add information about declaration specifiers<P>
defined with DEFINE-DECLARATION to the macroexpansion and evalhook<P>
environments.<P>
<P>
The consequences are undefined if DECL-NAME is a symbol which can<P>
appear as the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> of any declaration specifier defined in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A>.<P>
<P>
The consequences are also undefined if the return value from a <P>
declaration handler defined with DEFINE-DECLARATION includes a key name<P>
that is used by the corresponding accessor to return information about<P>
any declaration specifier defined in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A>. (For example, if<P>
the first return value from the handler is :VARIABLE, the second return<P>
value may not use the symbols <A REL=DEFINITION HREF="../Body/d_dynami.htm#dynamic-extent"><B>DYNAMIC-EXTENT</B></A>, <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>, or <A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>TYPE</B></A> as key<P>
names.)<P>
<P>
The DEFINE-DECLARATION macro does not have any special compile-time<P>
side-effects.<P>
<P>
<P>
PARSE-MACRO name lambda-list body &amp;optional env [Function]<P>
<P>
This function is used to process a macro definition in the same way<P>
as <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> and <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A>. It returns a lambda-expression that accepts<P>
two arguments (a form and an environment). The &quot;name&quot;, &quot;lambda-list&quot;,<P>
and &quot;body&quot; arguments correspond to the parts of a <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> or <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A><P>
definition.<P>
<P>
The &quot;lambda-list&quot; argument can include <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;ENVIRONMENT</B></A> and <A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&amp;WHOLE</B></A>. The &quot;name&quot;<P>
argument is used to enclose the &quot;body&quot; in an implicit <A REL=DEFINITION HREF="../Body/s_block.htm#block"><B>BLOCK</B></A>, and might also<P>
be used for implementation-dependent purposes (such as including the name of<P>
the macro in error messages if the form does not match the lambda-list).<P>
<P>
<P>
ENCLOSE lambda-expression &amp;optional env [Function]<P>
<P>
This function returns an object of type <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> that is equivalent to what<P>
would be obtained by evaluating `(<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> ,LAMBDA-EXPRESSION) in syntactic<P>
environment ENV. The LAMBDA-EXPRESSION is permitted to reference only the<P>
parts of the environment argument ENV that are relevant only to syntactic<P>
processing, specifically declarations and the definitions of macros and<P>
symbol-macros. The consequences are undefined if the LAMBDA-EXPRESSION<P>
contains any references to variable or function bindings that are <P>
lexically visible in ENV; any <A REL=DEFINITION HREF="../Body/s_go.htm#go"><B>GO</B></A> to a tag that is lexicaly visible in <P>
the environment ENV; or any <A REL=DEFINITION HREF="../Body/s_ret_fr.htm#return-from"><B>RETURN-FROM</B></A> a block name that is lexically <P>
visible in the environment ENV.<P>
<P>
<P>
<B>Rationale:<P>
</B><P>
This proposal defines a minimal set of accessors (VARIABLE-INFORMATION,<P>
FUNCTION-INFORMATION, and DECLARATION-INFORMATION) and a constructor<P>
(AUGMENT-ENVIRONMENT) for environments.<P>
<P>
All of the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> declaration specifiers, with the exception of <A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A>,<P>
can be defined fairly easily using DEFINE-DECLARATION. It also<P>
seems to be able to handle most extended declarations.<P>
<P>
The PARSE-MACRO function is provided so that users don't have to write their<P>
own code to destructure macro arguments. With the addition of<P>
<A REL=DEFINITION HREF="../Body/m_destru.htm#destructuring-bind"><B>DESTRUCTURING-BIND</B></A> to the language, this function is not entirely necessary.<P>
However, it is probably worth including anyway, since any program-analyzing<P>
program is going to need to define it, and the definition isn't completely<P>
trivial.<P>
<P>
ENCLOSE is needed to allow expander functions to be defined in a non-NULL<P>
lexical environment, as required by <A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL:ALLOW</A>. It<P>
also provides a mechanism by which the forms in an (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>) ...)<P>
can be executed in the enclosing environment (see Issue<P>
<A HREF="iss147.htm">EVAL-WHEN-NON-TOP-LEVEL</A>).<P>
<P>
Making declarations from an <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;ENVIRONMENT</B></A> or EVALHOOK environment optional<P>
continues to allow implementations the freedom simply to ignore all such<P>
declarations in the compiler or interpreter.<P>
<P>
<P>
<B>Examples:<P>
</B><P>
#1: This example illustrates the first two values returned by the function<P>
VARIABLE-INFORMATION.<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> KIND-OF-VARIABLE (VAR <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;ENVIRONMENT</B></A> ENV)<P>
(<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (KIND BINDINGP)<P>
(VARIABLE-INFORMATION VAR ENV)<P>
`(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> ',VAR ',KIND ',BINDINGP)))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defpar.htm#defvar"><B>DEFVAR</B></A> A)<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A> B 43)<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> TEST ()<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> (C)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> (D)<P>
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> D))<P>
(<A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>SYMBOL-MACROLET</B></A> ((E ANYTHING))<P>
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> (KIND-OF-VARIABLE A)<P>
(KIND-OF-VARIABLE B)<P>
(KIND-OF-VARIABLE C)<P>
(KIND-OF-VARIABLE D)<P>
(KIND-OF-VARIABLE E)<P>
(KIND-OF-VARIABLE F))))))<P>
<P>
(TEST) -&gt; ((A :SPECIAL <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
(B :CONSTANT <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
(C :LEXICAL T)<P>
(D :SPECIAL T)<P>
(E :SYMBOL-MACRO T)<P>
(F <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>))<P>
<P>
<P>
#2: This example illustrates the first two values returned by the function<P>
FUNCTION-INFORMATION.<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> KIND-OF-FUNCTION (<A HREF="iss174.htm">FUNCTION-NAME</A> <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;ENVIRONMENT</B></A> ENV)<P>
(<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (KIND BINDINGP)<P>
(FUNCTION-INFORMATION <A HREF="iss174.htm">FUNCTION-NAME</A> ENV)<P>
`(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> ',<A HREF="iss174.htm">FUNCTION-NAME</A> ',KIND ',BINDING)))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> A ())<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> A) (V))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> B ())<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> TEST ()<P>
(<A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> ((C ()))<P>
(<A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> ((D ()))<P>
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> (KIND-OF-FUNCTION A)<P>
(KIND-OF-FUNCTION B)<P>
(KIND-OF-FUNCTION <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A>)<P>
(KIND-OF-FUNCTION (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> A))<P>
(KIND-OF-FUNCTION C)<P>
(KIND-OF-FUNCTION D)<P>
(KIND-OF-FUNCTION E)))))<P>
<P>
(TEST) -&gt; ((A :FUNCTION <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
(B :MACRO <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A> :SPECIAL-FORM <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
((<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> A) :FUNCTION <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
(C :FUNCTION T)<P>
(D :MACRO T)<P>
(E <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>))<P>
<P>
<P>
#3: This example shows how a code-walker might walk a <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> special form.<P>
It assumes that the revised <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> semantics described in proposal<P>
<A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL:ALLOW</A> are in effect. <P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> WALK-MACROLET (FORM ENV)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((MACROS (MAKE-MACRO-DEFINITIONS (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cadr"><B>CADR</B></A> FORM) ENV)))<P>
(<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (BODY DECLS) (PARSE-BODY (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cddr"><B>CDDR</B></A> FORM))<P>
(WALK-IMPLICIT-PROGN<P>
BODY<P>
(AUGMENT-ENVIRONMENT ENV :MACRO MACROS :DECLARE DECLS)))))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> MAKE-MACRO-DEFINITIONS (DEFS ENV)<P>
(<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>MAPCAR</B></A> #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> (DEF)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((NAME (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> DEF)))<P>
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> NAME<P>
(ENCLOSE (PARSE-MACRO NAME (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cadr"><B>CADR</B></A> DEF) (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cddr"><B>CDDR</B></A> DEF) ENV)<P>
ENV))))<P>
DEFS))<P>
<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
Most implementations already record some of this information in some form.<P>
Providing these functions should not be too difficult, but it is a more than<P>
trivial amount of work.<P>
<P>
<B>Cost to Users:<P>
</B><P>
This change is upward compatible with user code.<P>
<P>
<B>Current practice:<P>
</B><P>
No implementation provides all of this interface currently. Portable Common<P>
Loops defines a subset of this functionality for its code walker and<P>
implements it on a number of diffent versions of Common Lisp.<P>
<P>
<B>Discussion:<P>
</B><P>
The first version of this proposal expressly did not deal with the objects<P>
which are used as environments by EVALHOOK. This version is extended to<P>
support them in the belief that such environments share a lot of functionality<P>
with the syntactic environments needed by a compiler. While the two types of<P>
environments might have very different implementations, there are many<P>
operations which are reasonable to perform on either type, including all of<P>
the accessor functions described by this proposal.<P>
<P>
There has been discussion about a macro called WITH-AUGMENTED-ENVIRONMENT,<P>
either in addition to or instead of AUGMENT-ENVIRONMENT. The point of this<P>
would be to say that the extent of the augmented environment is the dynamic<P>
extent of the WITH-AUGMENTED-ENVIRONMENT form. There was some concern that<P>
there might be cases where the macro was awkward to use. Such a macro is not<P>
included in this proposal. If AUGMENT-ENVIRONMENT is provided, then such a<P>
macro is trivially written in terms of the function. There are places in the<P>
processing of sequential binding forms where using such a macro might be more<P>
difficult than using the specified function.<P>
<P>
Some people have indicated they think that the :MACRO argument (and the<P>
:SYMBOL-MACRO argument too?) to AUGMENT-ENVIRONMENT should be an a-list of the<P>
form ((name . definition)...) rather than the form ((name definition)...).<P>
<P>
Some people have indicated they think that implementations must never discard<P>
any declarations, even if they are not otherwise used by the interpreter or<P>
compiler. Proposal SMALL is consistent with what CLtL says (implementations<P>
are free to ignore all declarations except <A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> declarations), but the<P>
DECLARATION-INFORMATION function might not be particularly useful unless it is<P>
guaranteed to do something. Requiring implementations to keep track of<P>
declarations they'd otherwise ignore would involve some implementation cost<P>
and also might incur a performance penalty.<P>
<P>
ENCLOSE happens to subsume the extension to <A REL=DEFINITION HREF="../Body/f_coerce.htm#coerce"><B>COERCE</B></A> for converting a <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A><P>
expression into a function (see Issue <A HREF="iss175_m.htm">FUNCTION-TYPE</A>, passed in June 1988).<P>
Perhaps the extension to <A REL=DEFINITION HREF="../Body/f_coerce.htm#coerce"><B>COERCE</B></A> should be backed out?<P>
<P>
There have been some suggestions for related functionality that have not<P>
been included in this proposal because we haven't had the time to give<P>
them adequate consideration, and some of them might be controversial.<P>
These suggestions include:<P>
<P>
- Adding a function to canonicalize type specifiers.<P>
<P>
- Extending VARIABLE-INFORMATION to return a value indicating whether there<P>
is a special binding of the variable in the environment, regardless of<P>
whether or not it has been shadowed by a lexical or symbol-macro binding<P>
of the same name.<P>
<P>
- A function to map over all names that are defined in the lexical <P>
environment:<P>
<P>
MAP-ENVIRONMENT fn key &amp;optional env<P>
<P>
KEY must be one of the symbols :FUNCTION, :VARIABLE, or :DECLARATION.<P>
<P>
when key is :FUNCTION,<P>
for every symbol S for which (FUNCTION-INFORMATION s ENV)<P>
would return the values X, true, Y, for any X and Y,<P>
FN is applied to the arguments S, X, and Y.<P>
<P>
when key is :VARIABLE,<P>
for every symbol S for which (VARIABLE-INFORMATION s ENV)<P>
would return the values X, true, Y, for any X and Y,<P>
FN is applied to the arguments S, X, and Y.<P>
<P>
when key is :DECLARATION,<P>
for every symbol S for which (VARIABLE-INFORMATION s ENV)<P>
would return a non-nil value L<P>
FN is applied to the arguments S and L. <P>
<P>
- Adding additional accessors and keyword arguments to AUGMENT-ENVIRONMENT<P>
for <A REL=DEFINITION HREF="../Body/s_block.htm#block"><B>BLOCK</B></A> and <A REL=DEFINITION HREF="../Body/s_tagbod.htm#tagbody"><B>TAGBODY</B></A> labels.<P>
<P>
<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>