[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
issue SYNTACTIC-ENVIRONMENT-ACCESS, version 5
- To: cl-compiler@sail.stanford.edu
- Subject: issue SYNTACTIC-ENVIRONMENT-ACCESS, version 5
- From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
- Date: Mon, 20 Mar 89 16:29:12 MST
- Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, masinter.pa@XEROX.COM, cperdue@Sun.COM
- In-reply-to: cperdue@Sun.COM (Cris Perdue), Mon, 20 Mar 89 14:18:31 PST
OK, here's a new, improved writeup on this issue that incorporates all
the changes we seem to have agreed on. If this doesn't say what you
thought it would, let me know.
Forum: Compiler
Issue: SYNTACTIC-ENVIRONMENT-ACCESS
References: CLtL Chapter 8: Macros
Issue MACRO-FUNCTION-ENVIRONMENT
Issue GET-SETF-METHOD-ENVIRONMENT
Issue COMPILE-FILE-ENVIRONMENT
Related Issues: Issue FUNCTION-NAME
Issue PROCLAIM-LEXICAL
Issue MACRO-ENVIRONMENT-EXTENT
Issue DESTRUCTURING-BIND
Category: ADDITION
Edit history: Version 1, 2-Oct-88, Eric Benson
Version 2, 17-Feb-89, Kim A. Barrett
Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
Version 4, 12-Mar-89, Sandra Loosemore (more revisions)
Version 5, 20-Mar-89, Sandra Loosemore (only proposal SMALL)
Status: **DRAFT**
Problem description:
When macro forms are expanded, the expansion function is called with
two arguments: the form to be expanded, and the environment in which
the form was found. The environment argument is of limited utility.
The only use sanctioned currently is as an argument to MACROEXPAND or
MACROEXPAND-1 or passed directly as an argument to another macro
expansion function. Recent cleanup issues propose to allow it as an
argument to MACRO-FUNCTION and to GET-SETF-METHOD.
It is very difficult to write a code walker that can correctly handle
local macro and function definitions, due to insufficient access to
the information contained in environments and the inability to
augment environments with local definitions.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):
The following functions provide information about syntactic
environment objects. In all of these functions the argument named ENV
is an environment of the sort received by the &ENVIRONMENT argument to
a macro or as the environment argument for EVALHOOK. (It is not
required that implementations provide a distinguished representation
for such objects.) Optional "env" arguments default to NIL, which
represents the local null lexical environment (containing only global
definitions and proclamations that are present in the runtime
environment). All of these functions should signal an error of type
TYPE-ERROR if the value of an environment argument is not a syntactic
environment.
The accessors VARIABLE-INFORMATION, FUNCTION-INFORMATION, and
DECLARATION retrieve information about declarations that are in
effect in the environment. Since implementations are permitted to
ignore declarations (except for SPECIAL declarations), these accessors
are required only to return information about declarations that were
explicitly added to the environment using AUGMENT-ENVIRONMENT.
Implementations are also permitted to canonicalize declarations, so
the information returned by the accessors may not be identical to
the information that was passed to AUGMENT-ENVIRONMENT.
VARIABLE-INFORMATION variable &optional env [Function]
This function returns information about the interpretation of the
symbol VARIABLE when it appears as a variable within the lexical
environment ENV. At least the following four values are returned;
implementations are permitted to extend this function to return
additional values.
The first value indicates the type of definition or binding which is
apparent in ENV:
NIL There is no apparent definition or binding for variable.
:SPECIAL VARIABLE refers to a special variable, either declared
or proclaimed.
:LEXICAL VARIABLE refers to a lexical variable.
:SYMBOL-MACRO VARIABLE refers to a SYMBOL-MACROLET binding.
:CONSTANT VARIABLE refers to a named constant, defined by
DEFCONSTANT.
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result
will also refer to variables proclaimed lexical.]
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, NIL is returned.
The third value is the type specifier associated with the variable
named by the symbol in the environment. If no explicit association
exists, either by PROCLAIM or DECLARE, then the result is the type
specifier T. It is permissible for implementations to return a type
specifier that is equivalent to or a supertype of the one appearing
in the original declaration.
The fourth value is true if the variable has been declared IGNORE.
If no such declaration has been made or the information is not
available, NIL is returned.
FUNCTION-INFORMATION function &optional env [Function]
This function returns information about the interpretation of the
function name FUNCTION when it in a functional position within
lexical environment ENV. At least the following four values are
returned; implementations are permitted to extend this function to
return additional values.
The first value indicates the type of definition or binding of
the function name which is apparent in ENV:
NIL There is no apparent definition for FUNCTION.
:FUNCTION FUNCTION refers to a function.
:MACRO FUNCTION refers to a macro.
:SPECIAL-FORM FUNCTION refers to a special form.
Some function names may refer to both a global macro and a global
special form. In such a case, the macro takes precedence, and
:MACRO is returned as the first value.
The second value specifies whether the definition is local or
global. If local, the second value is true, and it is false when
the definition is global.
The third value is the type specifier associated with the function
in the environment, or the symbol FUNCTION if there is no functional
type declaration or proclamation associated with the function. This
value might not include all the apparent FTYPE declarations for
FUNCTION. It is permissible for implementations to return a type
specifier that is equivalent to or a supertype of the one that
appeared in the original declaration.
The fourth value is one of the symbols :INLINE, :NOTINLINE, or NIL,
depending on whether the function has been declared INLINE or NOTINLINE.
NIL is returned if there are no such declarations present or if the
information cannot be determined.
[Note: The use of "function name" rather than "symbol" as the
description of the function argument is intended to be compatible
with the various proposals to extend the syntax of function
specifiers. If no such change actually occurs then this would only
refer to symbols.]
AUGMENT-ENVIRONMENT env &KEY variable
symbol-macro
function
macro
declare [Function]
This function returns a new environment containing the information
present in ENV, augmented with the information provided by the keyword
arguments. The arguments are supplied as follows:
:VARIABLE A list of symbols which shall be visible as bound
variables in the new environment. Whether each
binding is to be interpreted as special or lexical
depends on SPECIAL declarations recorded in the
environment or provided in the :DECLARE argument list.
:SYMBOL-MACRO A list of symbol macro definitions, specified as a
list of (name definition) lists (that is, in the same
format as the CADR of a SYMBOL-MACROLET special form).
The new environment will have local symbol-macro bindings
of each symbol to the corresponding expansion, so that
MACROEXPAND will be able to expand them properly.
:FUNCTION A list of function names which shall be visible as local
function bindings in the new environment.
:MACRO A list of local macro definitions, specified as a
list of (name definition) lists. Each definition 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 MACRO-FUNCTION and used by
MACROEXPAND.
:DECLARE A list of decl-specs. Information about these
declarations can be retrieved from the resulting
environment using the VARIABLE-INFORMATION,
FUNCTION-INFORMATION, and DECLARATION accessors.
An error is signalled if any of the symbols naming macros in the
:SYMBOL-MACRO alist are also included in the :VARIABLE list.
An error is signalled if any of the names specified as keys in the
:MACRO alist are also included in the :FUNCTION list. The consequences
of destructively modifying the list structure of any of the arguments
to this function are undefined.
The extent of the returned environment is the same as the extent of
the argument environment. The result may share structure with the
argument environment, but the argument environment is not modified.
While an environment argument from EVALHOOK is permitted to be used
as the environment argument for this function, the reverse is not
true. If an attempt is made to use the result of AUGMENT-ENVIRONMENT
as the environment argument for EVALHOOK, the consequences are
undefined. The environment returned by AUGMENT-ENVIRONMENT may only
be used for syntactic analysis, ie. the functions specified by this
proposal and functions such as MACROEXPAND.
PARSE-MACRO name lambda-list body &optional env [Function]
This function is used to process a macro definition in the same way
as DEFMACRO and MACROLET. It returns a lambda-expression that accepts
two arguments (a form and an environment). The "name", "lambda-list",
and "body" arguments correspond to the parts of a DEFMACRO or MACROLET
definition.
The "lambda-list" argument may include &ENVIRONMENT and &WHOLE.
The "name" argument is used to enclose the "body" in an implicit
BLOCK, and may 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 lambda-list).
DECLARATION decl-spec &optional env [Function]
This function returns a list of declaration-specifiers whose CAR
is the symbol DECL-SPEC that are in force in the environment ENV,
sorted so that the innermost declaration is first on the list.
It is required that this function recognize OPTIMIZE and DECLARATION
declarations. The results are unspecified for any other built-in
declaration-specifier.
If an implementation has been extended to recognize additional
declaration specifiers in DECLARE or PROCLAIM, it is required that
either the DECLARATION function should also recognize those
declarations, or that the implementation provide an accessor that is
specialized for that declaration specifier. Note that if an
extended declaration specifier may be "bound", this function should
return only those declarations that apply to the lexically visible
binding.
Rationale:
This proposal defines a minimal set of accessors and a constructor
for environments.
The PARSE-MACRO function is provided so that users don't have to
write their own code to destructure macro arguments. Most
implementations probably already have a similar internal function.
Making TYPE and FTYPE declarations optional continues to allow
implementations the freedom to simply ignore all such declarations.
The same holds true for other declarations accessed with the
DECLARATION function.
Examples:
#1: This example illustrates the first value returned by the function
VARIABLE-INFORMATION.
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-INFORMATION VAR ENV))
(DEFVAR A)
(DEFUN TEST ()
(LET (B)
(LET (C)
(DECLARE (SPECIAL C))
(SYMBOL-MACROLET ((D ANYTHING))
(LIST (KIND-OF-VARIABLE A)
(KIND-OF-VARIABLE B)
(KIND-OF-VARIABLE C)
(KIND-OF-VARIABLE D)
(KIND-OF-VARIABLE E))))))
(TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
#2: This example illustrates the first value returned by the function
FUNCTION-INFORMATION.
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(FUNCTION-INFORMATION FUNCTION-NAME ENV))
(DEFUN A ())
(DEFMACRO B ())
(DEFUN TEST ()
(FLET ((C ()))
(MACROLET ((D ()))
(MULTIPLE-VALUE-CALL #'LIST
(KIND-OF-FUNCTION A)
(KIND-OF-FUNCTION B)
(KIND-OF-FUNCTION QUOTE)
(KIND-OF-FUNCTION C)
(KIND-OF-FUNCTION D)
(KIND-OF-FUNCTION E)))))
(TEST) -> (:FUNCTION NIL
:MACRO NIL
:SPECIAL-FORM NIL
:FUNCTION T
:MACRO T
NIL NIL)
#3: This example shows how a code-walker might walk a MACROLET special
form.
(defun walk-macrolet (form env)
(let ((macros (make-macro-definitions (cadr form) env)))
(multiple-value-bind (body decls) (parse-body (cddr form))
(walk-implicit-progn
body
(augment-environment env :macro macros :declare decls))
)))
(defun make-macro-definitions (defs env)
(let ((results nil))
(dolist (d defs)
(push (list (car d)
(coerce (parse-macro (car d) (cadr d) (cddr d) env)
'function))
results))
results))
Cost to Implementors:
Most implementations already record some of this information in some
form. Providing these functions should not be too difficult, but it
is a more than trivial amount of work.
Cost to Users:
This change is upward compatible with user code.
Current practice:
No implementation provides all of this interface currently. Portable
Common Loops defines a subset of this functionality for its code
walker and implements it on a number of diffent versions of Common
Lisp.
Discussion:
The first version of this proposal expressly did not deal with the
objects which are used as environments by EVALHOOK. This version is
extended to support them in the belief that such environments share a
lot of functionality with the syntactic environments needed by a
compiler. While the two types of environments might have very
different implementations, there are many operations which are
reasonable to perform on either type, including all of the accessor
functions described by this proposal.
AUGMENT-ENVIRONMENT currently requires signaling an error when
symbol-macro names match variable names in the same call. This could
be reduced to "should signal". By requiring the error signaling, this
proposal is compatable with Proposal SYMBOL-MACROLET-DECLARE:ALLOW,
which says
"... signals an error if a SPECIAL declaration names one of the symbols
being defined as a symbol-macrolet."
Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal
allows fairly trivial implementations of the SYMBOL-MACROLET
special-form in terms of the AUGMENT-ENVIRONMENT function.
Moon notes:
Symbolics Genera includes an undocumented internal macro, used
quite a bit in the implementation of the interpreter and code
analyzers, that could have been called WITH-AUGMENTED-ENVIRONMENT,
taking keywords like AUGMENT-ENVIRONMENT and also body forms,
and producing an environment with dynamic extent bound to a
variable within the body forms. Would it be useful to have this
too, or instead of AUGMENT-ENVIRONMENT? I'm unsure.
Some people have indicated they think that the :MACRO argument (and
the :SYMBOL-MACRO argument too?) to AUGMENT-ENVIRONMENT should be an
a-list of the form (name . definition).
-------