[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Issue SYNTACTIC-ENVIRONMENT-ACCESS
- To: cl-compiler@SAIL.STANFORD.EDU
- Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
- From: Kim A. Barrett <IIM@ECLA.USC.EDU>
- Date: Thu 9 Mar 89 23:12:17-PST
- Cc: iim@ECLA.USC.EDU
Major changes from version 2.
1. ENVIRONMENT-TARGET => ENVIRONMENT-REMOTE-P
2. Dropped the ENVIRONMENT- prefix from the accessors, and made the env
arguments optional (Gray's suggestion).
3. TYPE and FTYPE information made optional.
4. AUGMENT-ENVIRONMENT: Replaced :lexical argument with :variable argument,
taking on the responsibility of seperating lexicals from specials based on
the :special argument and global proclamations.
5. New stuff: WITH-REMOTE-ENVIRONMENT, RECORD-ENVIRONMENT-CLEANUP, and
MAKE-NULL-ENVIRONMENT.
6. Significant rewrites of various sections in response to comments. Hopefully
this version will be found less confusing and better motivated.
kab
-----
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
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)
Status: For internal discussion
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.
Implementing the FIND-CLASS and ENSURE-GENERIC-FUNCTION functions of CLOS
requires the ability to distinguish between environments used for compiling to
a file from those used for processing in-core, such as by EVAL or COMPILE.
Resolution of the LOAD-TIME-EVAL issue may also require this information.
This problem has been addressed by the recent cleanup issue
COMPILE-FILE-ENVIRONMENT. Also, it has proven impossible to write a portable
code walker in Common Lisp, due to insufficient access to the information
contained in environments and the inability to augment environments with local
function definitions.
Proposal (SYNACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE):
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. NIL is the local null lexical environment,
and is therefore considered to be a syntactic 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.
ENVIRONMENT-REMOTE-P env [Function]
Returns true if ENV is a remote environment, false otherwise.
VARIABLE-KIND variable &optional env [Function]
VARIABLE is a symbol. This function returns one of the folloing symbols,
depending on 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.]
Example:
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-KIND 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)
FUNCTION-KIND function &optional env [Function]
FUNCTION is a function name. This function returns two values, depending on
the type of function definition or function binding which is apparent for
FUNCTION 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.
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.
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.
[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.]
Example:
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(FUNCTION-KIND 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)
VARIABLE-TYPE variable &optional env [Function]
VARIABLE is a symbol. This function returns 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.
The result of this function may not include all the apparent TYPE
declarations for VARIABLE. In particular, an implementation is free to
ignore TYPE declarations, only returning TYPE information which was added to
ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records type information in the
environment, rather than ignoring it.
(DEFMACRO VARTYPE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-TYPE VAR ENV))
(DEFVAR A 1)
(PROCLAIM '(FIXNUM A))
(DEFUN TEST ()
(LET ((B (AREF "X" 0))
(C 3))
(DECLARE (STRING-CHAR B))
(LIST (VARTYPE A) (VARTYPE B) (VARTYPE C))))
(TEST) -> (FIXNUM STRING-CHAR NIL)
FUNCTION-FTYPE function &optional env [Function]
FUNCTION is a function name. This function returns the functional 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.
The result of this function may not include all the apparent FTYPE
declarations for FUNCTION. In particular, an implementation is free to
ignore FTYPE declarations, only returning FTYPE information which was added
to ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records ftype information in the
environment, rather than ignoring it.
(DEFMACRO FUNTYPE (FUN &ENVIRONMENT ENV)
`',(FUNCTION-FTYPE FUN ENV))
(DEFUN A-FUNCTION (X)
(+ X 3))
(PROCLAIM '(FTYPE (FUNCTION (FIXNUM) FIXNUM) A-FUNCTION))
(DEFUN TEST ()
(FLET ((ANOTHER-FUNCTION (X)
(+ X 2)))
(DECLARE (FTYPE (FUNCTION (INTEGER) INTEGER) ANOTHER-FUNCTION))
(LIST (FUNTYPE A-FUNCTION) (FUNTYPE ANOTHER-FUNCTION))))
(TEST) -> ((FUNCTION (FIXNUM) FIXNUM) (FUNCTION (INTEGER) INTEGER))
AUGMENT-ENVIRONMENT env &KEY variable
special
symbol-macro
function
macro
type
ftype [Function]
This function returns a copy of 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 dynamic or lexical depends on the value of the :SPECIAL
argument and SPECIAL proclamations recorded in the environment.
:SPECIAL A list of symbols which shall be visible as dynamic variables
in the new environment. If a symbol in this list also appears
in the :VARIABLE list, then the binding is to be interpreted as
being dynamic.
:SYMBOL-MACRO An alist of symbols and macroexpansions. 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 An alist of function names and macroexpansion functions. 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.
:TYPE An alist of symbols and type specifiers. The new environment
will have the type specifier associated with the currently
visible binding of the symbol (defaulting to the global special
binding if there is no binding present). Note that in a single
call to AUGMENT-ENVIRONMENT the :TYPE argument can be thought
of as being processed after all the variable arguments have
been processed, thus allowing bindings and declarations to be
updated with a single call.
:FTYPE An alist of function names and functional type specifiers.
This is analogous to :TYPE, exept operating in the function
namespace.
An error is signaled if any of the symbols specified as keys in the
:SYMBOL-MACRO alist are also included in either the :VARIABLE or :SPECIAL
lists, or are among the key symbols in the :TYPE alist. An error is signaled
if any of the names specified as keys in the :MACRO alist are also included
in the :FUNCTION list. It is an error to modify the list structure of any of
the arguments to this function.
If the ENV argument is a remote environment, then the new environment
returned by this function will also be remote, and the two will refer to the
same model of the remote environment. The extent of the returned environment
is the same as the extent of the argument.
While an environment argument from EVALHOOK may be used as the environment
argument for this function, the reverse is not true. It is an error to
attempt to use the result of AUGMENT-ENVIRONMENT as the environment argument
for EVALHOOK. 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.
[Note: Some modification to this will be required to support Issue
PROCLAIM-LEXICAL if it is adopted. The changes would involve adding a
:LEXICAL keyword similar to :SPECIAL, and fixing up the error signaling
cases.]
ENVIRONMENT-PROPERTY env name property &optional default
This function and its SETF method allow the association of arbitrary 'global'
properties with names within an environment. An environment can be thought
of as having a local property list associated with any name, and this
function provides access to that property list.
A remote environment may be thought of as an extension of the local
environment. Thus, when this function is applied to a remote environment and
the property is not found, the local environment is then searched.
The association between names and property lists uses EQUAL to match names.
The search of the property list uses EQ to match properties. If the property
is not found, DEFAULT is returned.
Using SETF of ENVIRONMENT-PROPERTY affects all environments which refer to
the same environment model. In particular, if ENV is a local environment
then all local environments are affected, while if ENV is a remote
environment, then all environments refering to the same remote environment
model as the argument are affected.
[Note: The local property list of a name is not necessarily the symbol-plist
of the name, though that is a possible implementation for names which are
symbols.
Note: The use of EQUAL as the matching function for names is to allow for
proposed extensions to function names. If no such extension occurs, then EQ
could be used instead.]
WITH-REMOTE-ENVIRONMENT var &body body [Macro]
Evaluates the BODY forms with VAR bound to a newly created remote
environment. The extent of the environment is the dynamic extent of the
WITH-REMOTE-ENVIRONMENT form. Before the extent is exited, each of the
cleanup functions specified by RECORD-ENVIRONMENT-CLEANUP is called with the
environment as its argument. The order in which the cleanup functions are
called is unspecified.
This is the only specified mechanism by which a new remote environment may be
created.
RECORD-ENVIRONMENT-CLEANUP env function [Function]
Record a function to be called when the extent of the environment is exited.
An error of type TYPE-ERROR is signaled if ENV is not a remote environment.
When the extent of ENV ends, FUNCTION will be called with one argument, an
environment which refers to the same remote environment model as the argument
environment.
[Note: The present author does not like the name of this function.
Suggestions solicited.]
MAKE-NULL-ENVIRONMENT &optional env [Function]
Create and return a NULL lexical environment. The ENV argument is used to
determine whether the new environment should be local or remote. If remote,
the two will refer to the same model of the remote environment. The extent
of the returned environment is the same as the extent of the argument.
Rationale:
This proposal provides a portable interface to environment information which
must otherwise be obtained by implementation-dependent means. The
ENSURE-GENERIC-FUNCTION and FIND-CLASS functions of CLOS require the
ENVIRONMENT-REMOTE-P function and some mechanism similar to that supplied by
the ENVIRONMENT-PROPERTY function. A useful code walker requires the
capability of adding local function definitions to an environment.
Making TYPE and FTYPE information optional continues to allow implementations
the freedom to simply ignore all such declarations.
WITH-REMOTE-ENVIRONMENT and RECORD-ENVIRONMENT-CLEANUP provide functionality
which some people believe is needed to implement some of the remote metaobject
mechanisms in CLOS.
MAKE-NULL-ENVIRONMENT is provided for use by code-walkers, so that they can
handle occurances of special-forms like LOAD-TIME-EVAL, which requires a NULL
lexical environment.
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. IIM uses the
functionality provided by ENVIRONMENT-REMOTE-P and ENVIRONMENT-PROPERTY (under
other names) to implement the association between names and remote metaobjects
(macro and type definitions, CLOS remote metaobjects, &etc).
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 may 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.
An possible alternative syntax for WITH-REMOTE-ENVIRONMENT might be
WITH-REMOTE-ENVIRONMENT (var &key) &body body
Can anyone suggest candidates for keyword options? We could do this even if
we can't think of any immediately, leaving room for implementation-specific
extensions. One candidate option that some implementations might want would
be to specify a target machine for the compilation.
Kim Barrett originally suggested that WITH-COMPILATION-UNIT should provide the
mechanism for creating new remote environments. However, it has been
suggested that WITH-COMPILATION-UNIT is intended to serve a somewhat different
purpose. Also, that proposal doesn't seem to be getting much attention due to
time constraints, and this proposal needs to have such a mechanism specified.
â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â?
-------