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


Here's a new issue that discusses something that came up in relation
to issue COMPILER-LET-CONFUSION, namely the extent of &environment

Forum:		Compiler
References:	CLtL p. 145-146
Edit History:   V1, 10 Jan 1988, Sandra Loosemore
Status:		**DRAFT**

Problem Description:

What is the extent of environment objects received as the &ENVIRONMENT
argument of a macro function?

CLtL says that &ENVIRONMENT is "useful primarily in the rare cases
where a macro definition must explicitly expand any macros in a
subform of the macro call before computing its own expansion".  While
this suggests that macro environment objects are typically used within
the dynamic scope of the macro function, the use of the word
"primarily" (rather than "only" or "exclusively" or some similarly
strong language) suggests that there may be other legitimate uses for
environment objects.  But, because CLtL is silent about what those
uses might be, many users and implementors are under the impression
that environment objects have only dynamic extent.

There are some situations where using environment objects as if they
had indefinite extent provides a very useful viewpoint from which to
solve a problem.  Consider the following example:

  (defmacro typed-var (var) var)

  (defmacro local-type-declare (declarations &body forms &environment env)
      `(macrolet ((typed-var (&whole w var)
		    (let ((type  (assoc var ',declarations)))
		      (if type 
		          `(the ,(cadr type) ,var)
                          (macroexpand w ',env)))))

  (defun f (x y)
    (local-type-declare ((x fixnum) (y float))
      (+ (typed-var x) (typed-var y))))

Here, local macro TYPED-VAR is defined to look first in the innermost
lexical environment for information about the variable, and if there
isn't any then it recurses on the next outermost lexical environment.
The global definition of TYPED-VAR provides a terminal case to stop
the recursion.


State that macro environment objects received with the &ENVIRONMENT
argument of a macro function have indefinite extent.

Note that implementations are not permitted to destructively modify
environment objects once they have been passed to a macro function.


  This legitimizes the use of macro environments as shown in the
  example above.

  Since data objects in Lisp otherwise have indefinite extent, it is
  more consistent to give environment objects indefinite extent as


State that macro environment objects received with the &ENVIRONMENT
argument of a macro function have only dynamic extent; it is an error
to refer to them outside the dynamic extent of that macro function.


  This allows implementations to use somewhat more efficient techniques
  for representing environment objects.  For example, the storage could
  be stack-allocated, or environments could be bashed destructively
  instead of always being freshly heap-allocated.

Current Practice:

Macro environments appear to have indefinite extent in Lucid Common

A-Lisp also supports indefinite extent for macro environments and
internally uses this feature extensively.  For example, the FLET,
LABELS, and FUNCTION special forms are implemented as macros using
this feature.

Cost to implementors:

For proposal INDEFINITE, some implementations may need to change.  A
simple implementation of macro environments that would fit the
requirements of this proposal is to represent them as lists, pushing
information for inner contours onto the front of the list as the
contour is entered and popping the list when the contour is exited.

For proposal DYNAMIC, there is no associated implementation cost.

Cost to users:

For proposal INDEFINITE, there is no associated cost to users.

For proposal DYNAMIC, users would not be able to portably use a
simple and elegant approach to solving certain kinds of problems.


It is made clear whether treating environment objects as if they had
indefinite extent is portable usage.