[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue SYNTACTIC-ENVIRONMENT-ACCESS



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.
â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? â? 
-------