[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: user interface macros
- To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, David Gray <gray@lucid.com>, Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Jon L White <jonl@lucid.com>
- Subject: Re: user interface macros
- From: Gregor J. Kiczales <gregor@parc.xerox.com>
- Date: Wed, 2 May 90 16:13 PDT
- Cc: Danny Bobrow <bobrow@parc.xerox.com>, rivieres@parc.xerox.com, Richard P. Gabriel <rpg@lucid.com>, Dussud@Lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM
- In-reply-to: <19900426154319.8.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9004270038.AA00272@black-monday>, <19900427215856.1.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9004280008.AA02801@ptl-club>, <19900428011147.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <19900501195931.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>
Your messages raise a number of issues. In this message I attempt to
address them all, with the exception of simple typos and other obvious
screw-ups (I will correct those though).
This message is divided into two parts. The first part addresses
comments about the nature of the macroexpansion specification and
tries to show my sense of what it is appropriate to be saying at
this time. The second part deals with specific issues that were
raised.
ON THE NATURE OF THE GOALS (of this section as it relates to the whole)
Date: Fri, 27 Apr 90 17:08:50 PDT
From: Jon L White <jonl@lucid.com>
To what end specify the macro expansions exactly?
These are good questions and ones I have spent some time wrestling with
as well. In fact, as you yourself point out, the current draft attempts
not to say anything about the expansions themselves. Instead, it tries
to talk only about the various calls that result from evaluation or
executing a macro.
The question then becomes why even bother to do that. The main reason
is to allow user-defined metaobject classes to be instantiated by the
standard macros. You want DEFCLASS to be able to create instances of
MY-CLASS, you want DEFMETHOD to be able to create instances of MY-METHOD
etc.
Rather, I think the only point of mentioning the expansion of the
definer "user interface" macros is that our experience with metaobject
creations over the past two years, via portable constructs, *had* to
be limited to these macros.
I don't have any idea what this sentence means.
The goal of this document is to specify the behavior of the anonymous
metaobjects -- that is what is powerful and interesting. But, to do so
properly, requires that we say some things about the rest of the CLOS
mechanisms. We need to talk about the macroexpansion layer for the
reasons mentioned above. We need to talk about the name-->object
mapping layer because many user metalevel programs want to blend with
the name--> object mapping already used in `conventional' CLOS programs.
These aren't the most interesting parts, but they are essential to the
success of the whole.
What is perhaps unfortunate is that this round of work is starting with
macroexpansion -- that decision was made because that is the part of the
old document that was in the worst shape. We just have to remember that
this isn't the part we really care about. That we just need to do
enough ui macro stuff to enable the kinds of things users need to do as
mentioned above.
For example, Scott proposes a full-featured mechanism for metaclass
control over the parsing of DEFCLASS forms into calls to ENSURE-CLASS.
I have experimented with things like this in the past, and the one Scott
proposes is a nice one. But, I don't think we want to specify this sort
of thing right now. I feel like it is more than we want to get into,
especially given JonL's valid points that the uimacros are the least
important part of this whole thing.
I would rather do some combination of changing the specified behavior of
the ui macros and explicitly allowing this kind of implementation
specific extension. I could be argued out of this, especially if
someone else wrote the relevant text (Scott has a start).
So, on the subject of extending the syntax of DEFCLASS, I propose:
- remove the part about what happens when an option (any option) is
specified more than once. Just say it is not specified, that
implementations are free to document their own behavior.
- either
- fix the :metaclass and :documentation class options and leave
the stuff about the tail of the list (this is what I had in
mind originally and failed to write)
or
- make the class options (other than :default-initargs) pass
the CADR
- explicitly mention that implementations are free to have specific
mechanisms for extending the behavior of the ui macros.
- fix the stuff about order to say only:
- the order of :default-initargs is preserved
- and possibly that for unspecified slot and class options,
they the specified ones and their order is preserved
ON SPECIFIC ISSUES
Date: Thu, 26 Apr 90 11:43 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
First fix the confusion of using "compile" both to mean "translate to
machine code" and also to mean "write a file that can later be loaded
and will produce similar objects." You'll know you've got it right when
the specification does not admit any difference between EVAL and calling
the result of COMPILE. You're concerned with the case of one Lisp or
two (the compiling lisp and the loading/running Lisp), but you're not
concerned with whether the representation of Lisp programs is
S-expressions or machine code. I suggest eliminating all use of the
word "compile" except in the compound form "compile-file."
Yes, I was trying to head in this direction, but as we have all learned
it isn't so easy. The part about allowing DEFGENERICs that appear in
compiled files to affect the way DEFMETHOD forms are processed is, of
course, what makes it hard.
I will give this another go.
Date: Thu, 26 Apr 90 17:38:26 PDT
From: David Gray <gray@lucid.com>
Rather than "evaluates the initform", I would prefer that the wording be
modified to make it clear that it is permissible for the compiler to
substitute something that has an equivalent effect. For example,
:INITFORM (* 2 5)
could result in
:INITFUNCTION #'(LAMBDA () 10)
How about "returns the result of evaluating the initform in the lexical
environment of the DEFCLASS form"?
Date: Fri, 27 Apr 90 17:58 EDT
From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM,
Moon@STONY-BROOK.SCRC.Symbolics.COM
User interface macro forms can be {\bit evaluated}, {\bit compiled}, or a
compiled macro form can be {\bit executed}.
This sentence is a bit confusing. I think it meant to say
"User interface macro forms can be {\bit evaluated} or {\bit compiled}
and {\bit executed}." Since that is true of all macros, I'm not really
sure why it needs to be said at all.
The purpose of the sentence was to define the three terms. I will try
and fix this as mentioned above.
In the arguments to ENSURE-CLASS, this document has :DIRECT-SUPERCLASSES and
:DIRECT-SLOTS where 89-003 has :SUPERCLASSES and :SLOTS. Symbolics CLOS uses
:DIRECT-SUPERCLASSES (based on mail with Gregor a few months ago) but :SLOTS.
For consistency, :DIRECT-SLOTS would be better, but we've passed the point of
being able to remove :SLOTS, although we could make :SLOTS mean :DIRECT-SLOTS.
Similarly, :DIRECT-DEFAULT-INITARGS should replace :DEFAULT-INITARGS.
Although no document and no implementation uses :DIRECT-DEFAULT-INITARGS
currently, it would be more consistent.
It's difficult for me to tell what you are asking for here. The change
to :DIRECT-XXX was based on the mail you mention. I really think these
are better names. Unless someone complains I would like to leave these
as:
:DIRECT-SLOTS
:DIRECT-SUPERCLASSES
:DIRECT-DEFAULT-INITARGS
A canonicalized default initarg is a list of three elements.
...
Symbolics CLOS and 89-003 put the form before the function. Why was the order
gratuitously changed?
Also, there needs to be provision for implementation additions (we use one),
just as in the canonicalized slot specification. Just allow the list to have
more than three elements, where elements after the first three are
implementation dependent.
I will change the order back and allow the lists to be longer. But, for
reference:
* I believe the order in draft 11 is better because it makes the
implementation-specific `improvement' where you drop the form
more straighforward.
* I don't think making the lists longer is the most modular way
to do the extension you mention. Instead, another keyword
argument/initarg which parallels this one should be used.
The name in 89-003 and in Symbolics CLOS is generic-function-method-class.
Why the gratuitous change?
Braino, I will change it back.
\item{\bull} The value of the {\bf :specializers} initarg is a list of the
specializer names for the method. For {\bf eql} specializers, this is a
list in which the first element is the symbol {\bf setf} and the second
element is the result of evaluating the eql specializer form in the lexical
environment of the {\bf defmethod} form. For any other kind of
specializer, this is the value from the {\bf defmethod} form with no
special processing done.
It's too weird to make this a list of elements that are parameter specializers
in one case and parameter specializer names in the other case. 89-003 p.3-69
requires parameter specializers here, i.e. classes rather than class names.
See also 89-003 p.3-16. So not only is this weird, it's also a gratuitous
incompatibility.
Actually, I don't think its weird, but I am willing to change it back.
I believe, as I alluded to before, that there are three layers.
1) the macroexpansion layer
2) the name to metaobject mapping layer
3) the anonymous metaobjects (where the real CLOS behavior is)
The way this worked in 89-003 and the way you have it puts stuff from
layer 2 in layer 1, and that isn't modular.
\item{\bull} The {\it direct superclasses} argument to {\bf defclass}
becomes the value of the {\bf :direct-superclasses} keyword argument to
{\bf ensure-class}.
We do this differently. If the {\it direct superclasses} is NIL, then the
metaclass is asked for the list of direct superclasses to be used, using
class-default-direct-superclasses. For STANDARD-CLASS, (STANDARD-OBJECT) is
used, for FUNCALLABLE-STANDARD-CLASS, (FUNCALLABLE-INSTANCE), etc. Thus
ENSURE-CLASS receives the actual list of direct superclasses. In our way of
defaulting these, it is possible for a metaclass to make classes which have no
superclasses. The result of class-default-direct-superclasses is a list of
class objects even though the :direct-superclasses is otherwise a list of
class names; this might be a mistake, but does allow for anonymous classes
as default direct superclasses.
This is a similar issue. Defaulting the superclasses doesn't seem to me
to be a macroexpansion issue. It seems to me that defaulting the
superclasses is an essential part of the behavior of the raw object
system. Once again though, I can live with it this way.
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: Fri, 27 Apr 90 17:58 EDT
From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM,
Moon@STONY-BROOK.SCRC.Symbolics.COM
When defmethod calls ensure-generic-function, it must not supply the
:lambda-list argument. ensure-generic-function has to know the difference
between a call from defgeneric (which always replaces the lambda-list),
and a call from defmethod (which never replaces the lambda-list).
Symbolics CLOS works as outlined in this message:
Date: Fri, 27 Apr 90 17:08:50 PDT
From: Jon L White <jonl@lucid.com>
A gap in the current definition of ENSURE-GENERIC-FUNCTION?
Based on the comments you have sent, here is a strawman. What if we
have ENSURE-GENERIC-FUNCTION accept two keyword arguments: :LAMBDA-LIST
and :METHOD-LAMBDA-LIST.
The :LAMBDA-LIST argument will be passed in by DEFGENERIC. Its value
will the the value specified in the macro form. Its presence (or
non-nullness) will indicate the call was from DEFGENERIC.
The :METHOD-LAMBDA-LIST argument will be passed in by DEFMETHOD. Its
value will be the unspecialized lambda list from the macro form
(what you get by calling extract-lambda-list). Its presence (or
non-nullness) will indicate the call was from DEFMETHOD.
This means that special processing will happen inside of ENSURE-GF and
initialization when DEFMETHOD creates a generic function, but this
scheme should make all the information each of you wants available.