# user interface macros: the environment issue

It might pay to read this message starting at the end, unless you don't
remember all the context.

Date: Tue, 1 May 90 15:59 EDT
From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM

This document defines just enough of the compiler processing of the user
interface macros to allow portable metaobject classes to determine whether
instances are being created to represent definitions in the compile file
environment.  In such cases, the values of other keyword and initialization
arguments may differ from the specified values so portable code must test
for such cases to prevent encountering unexpected values.

Testing for these cases is possible because compiler processing of the
user-interface macros calls the functions {\bf ensure-class} and {\bf
ensure-generic-function} with a non-null value for the {\bf :environment}
keyword argument.

Defining NULL to be the predicate that tests whether an environment is the
run-time environment is not very abstract.  This could run into serious
problems with future extensions that unify this environment with the
&environment argument to macros or that implement more than just the run-time
and compilation environments.  On the one hand, NIL might not be the only
representation for the "ordinary" environment, and on the other hand, there
might be several distinct environments that all have the property of
containing classes that can be instantiated and methods that can be executed.

I didn't include in this message my later message expanding on the previous
two sentences.  I hope they're clear now.

I think we must choose either not to document any predicates on the
environment, and require portable metaobject classes to operate some other
way, or else to add one or more predicates that perform the specific tests on
environments that are actually needed.  I was unable to figure out what
specific predicates are needed, nor what the specific problem is that needs to
be solved (alluded to in "testing for these cases" above).  As a strawman,
I'll suggest (RUN-TIME-ENVIRONMENT-P env) => true if env is an environment
that causes FIND-CLASS to return instantiable classes and causes
ENSURE-GENERIC-FUNCTION to return callable generic functions.

The term "run time environment" is from section 4.2 of the draft ANSI CL
specification, revision 7.31 of 8/29/89.

[from our example of how option parsing could be done:]
The function COMPILE-FILE-ENVIRONMENT takes an environment as an argument
and returns an object with indefinite extent which has the same
COMPILE-FILEness properties as its argument.

That function probably has the wrong name.  The basic idea is that since Common
Lisp does not allow a macro to incorporate its &environment argument into the
expansion it returns, a macro that needs to do something like that (as DEFCLASS
does), has to pass the &environment argument through a function that makes it into
a sanitized argument with the same semnatics but indefinite extent.  This is only
needed as part of the protocol if users are making their own macros that resemble
DEFCLASS or DEFMETHOD -and- if those macros need to play eval-when games.  So I

Date: Wed, 2 May 90 16:13 PDT
From: Gregor J. Kiczales <Gregor.PA@Xerox.COM>

Defining NULL to be the predicate that tests whether an environment is the
run-time environment is not very abstract.  This could run into serious
problems with future extensions that unify this environment with the
&environment argument to macros or that implement more than just the run-time
and compilation environments.  On the one hand, NIL might not be the only
representation for the "ordinary" environment, and on the other hand, there
might be several distinct environments that all have the property of
containing classes that can be instantiated and methods that can be executed.

I agree with all of these comments.  What if we just added an argument
:COMPILE-ENVIRONMENT-P or something.  It would be true or false.  In
cases where it is true it would mean the some other information, passed
in implementation-specific keyword arguments had the real compile
environment.

Date: Thu, 3 May 90 11:47:44 PDT
From: David Gray <gray@lucid.com>

No, there should be just one environment argument.

I agree 100%.  I'd also like to add that any time you add more arguments
rather than making the extsing argument more expressive, you are not
adhering faithfully to the object-oriented religion.

Perhaps there should be
a function to test whether it is a compile-time environment (NULL is most
certainly not that function), but I would want to see the need for that
demonstrated first.  For the metaclass writer, the point is to be
MACROEXPAND, ENSURE-GENERIC-FUNCTION, etc.

Date: Thu, 3 May 90 12:21 PDT
From: Gregor J. Kiczales <Gregor.PA@Xerox.COM>

My idea was that the predicate would be the extra argument.  User code
would still be required to pass the argument on to the other functions
(find-class etc.).  User code would pass the value of the :environment
argument, no other values.  The other argument would just be a flag to
user code that this was in the compile environment and things might be
weird.

So "user code" would get information from one argument and "system code"
would get the same information from a different argument?  Since I don't
believe there is any real difference between "user code" and "system code",
and since specific pieces of code often migrate from one category to the
other (in both directions, in fact), I don't think this will fly.

Date: Thu, 3 May 90 13:21:20 PDT
From: David Gray <gray@lucid.com>

That still seems like an undesirable and unnecessary complication; I'd
rather have a predicate function than a redundant argument.

Date: Fri, 4 May 90 17:59 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

There is the additional issue of whether such a predicate is needed
at all.  Moon and Cyphers said:

I was unable to figure out what specific predicates are needed, nor
what the specific problem is that needs to be solved (alluded to in
"testing for these cases" above).

Gray said:

I would want to see the need for that demonstrated first.

So I think we agree that we're not yet convinced such a predicate is
needed.  Gregor hasn't addressed this issue yet.

Let's start by addressing the question of whether any predicates on
environments are needed at all, and if so, what exactly those predicates
are testing for.  My strawman proposal is that the metaobject protocol
documents no operations on environments other than the ones that are
already in 88-002R (such as the environment argument to FIND-CLASS) and
obvious extensions of the same thing.  Thus no run-time versus
compile-time predicate at all.  Let's look at where this breaks down,
if at all, to see whether there is a need for anything else.  I know
it will break down for users writing their own macros that do what
DEFCLASS does.  I haven't yet been shown a case where it will break down
for users writing methods that get called by the expansion of any of the
defining macros.