[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Compilation dependencies in CLOS
- To: lgm@ihlpf.att.com
- Subject: Compilation dependencies in CLOS
- From: Jon L White <jonl@lucid.com>
- Date: Tue, 20 Mar 90 20:54:07 PST
- Cc: commonloops.pa@Xerox.COM
- In-reply-to: lgm@ihlpf.att.com's message of Tue, 20 Mar 90 16:04 CST <900320-141517-2123@Xerox>
- Redistributed: commonloops.pa
You ask some very good questions, Larry, I hope they will be remembered
when the X3J13 proposal is sent out for public review.
-- Concering the phrase of CLtL/2e "the compiler "may also assume that
a class defined by DEFCLASS in the compile-time environment will be
defined in the run-time environment in such a way as to have the same
superclasses and metaclass."
I think you are right in saying that, taken to the extreme, this is an
untenable constraint. But I vaguely felt that the tenor of the X3J13
group was that this was a miminal requirement that at ***load-time***,
as opposed to the full duration of run-time, the class would be defined
as described.
It probably didn't get said very well in the X3J13 documents, and hence
probably not very well in CLtL/2e, because there was hope by some folks
that we could all agree on what a "virtual compilation environment" should
mean. When the compiler would encounter a DEFCLASS in a file, it would
effectively "evaluate" that form in the virtual environment set up to
represent the ultimate runtime image; but it would not evaluate the form
in the top-level environment of the compiler's image. The reason for such
a plan is somewhat akin to the cross-compilation problem -- that you don't
want the mere act of compiling a file that happens to contain definitions
contradicting those in the running image to destory that compiler's running
image.
So "virtual environments" didn't make it. But thinking about them
apparently diverted some energy that might otherwise have been spent
clarifying paragraphs like the one you quote above. Incidentally, the
problem is not limited to DEFCLASS; I think it may not be so easy to
ascertain whether the compiler, when encountering a top-level DEFMACRO
in a file:
(1) must evaluate the defmacro form, possibly "un-doing" the definition
at the end of the compile-file (or "compilation unit") scoping;
(2) must NOT evaluate the defmacro form;
(3) must NOT evaluate the defmacro form, but MUST make it available
for macroexpansion in subsequent code to be compiled in the file;
(4) choose exactly one of (1), (2), or (3);
(5) none of the above.
-- Concering the phrase of CLtL/2e: "Any accessors specified by
WITH-ACCESSORS must already have been defined before they are used."
I think "used" means "actually called, at runtime"; it doesn't mean the
more fearsome "referenced by previously processed code". By analogy, any
function automatically generated by a :writer slot option must be
defined before it is used. Now, in my opinion, this restriction is
too trivial to be worth mentioning; and as your extensive critique
shows, it even seems to be misleading.
-- Concering your question:
A third difficulty I have is with the use of undefined classes.
Consider a DEFCLASS which in its superclass list includes a name
not yet defined as a class; or a DEFMETHOD which has a parameter
specializer name that is not yet defined as a class. Can/Must a
CLOS implementation permit such references to undefined classes?
88-002R, page 2-24 states that an implementation must allow "forward
references" in other class definitions. However it also says that a class
must be defined before it may be "used" as a parameter specializer in a
method. Effectively, this means that a DEFMETHOD may not be evaluated
until all its specialized classes are (fully?) defined. Note that the
compiler can compile top-level calls to DEFMETHOD without evaluating them.
-- Concering your question:
What operations (e.g., FIND-CLASS) are legal on a
"forward-referenced class"? When such a class is later defined
via DEFCLASS, are all previous references guaranteed to work
properly without recompilation?
The only "previous references" that could exist are in the superclass
lists of other class definitions. A metaobject protocol would permit
some way of finding out whether or not a class was "fully defined",
meaning none of its direct superclasses are "forward" references, and
all of its direct superclasses are themselves fully defined. But alas
we didn't get that part of CLOS into the spec -- not even into the
"de facto metaobject standard" proposal that Dave Moon and I worked up
earlier this year, and which was sent out to selected mailing lists as:
Date: Sun, 4 Mar 90 18:28 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proposed de facto standard subset of metaobjects
To: Common-Lisp-Object-System@MCC.COM
. . .
However, I did raise just this question to the X3J13 community back
in January [and there were no electronic replies, but several verbal
replies saying that FIND-CLASS shouldn't "find" forward references]:
Date: Wed, 10 Jan 90 05:12:51 PST
From: Jon L White <jonl@lucid.com>
To: x3j13@sail.stanford.edu
Cc: cl-cleanup@sail.stanford.edu
Subject: FIND-CLASS for "forward-referenced" classes?
Should FIND-CLASS find a "class" that has only been mentioned in a
forward-referenced way, as a direct-superclass of a non-finalized class?
Does the name of such "class" constitue a valid type-specifier? E.g.,
(defclass FOO (BAR) (a b c))
defines a non-finalized class named FOO, but does it define one named BAR?
Chapters 1&2 of the CLOS specification do not specify how one should
arrange to make "forward" references to superclasses work. Chapter 3
suggest somewhat indirectly an implementation technique of actually
creating a class object, to use as a stub, for such a reference. But
there seems to be no requirement that it must be implemented this way;
some implementations do it this way, and some apparently just keep
around internal lists of the class names that were referenced in a
"forward" way.
Arguing against letting FIND-CLASS return a forward-referenced-class
object is that the existence of such an actual class-object is merely an
implementational artifact, and may not even be portable. From a larger
point of view, one could ask why the mere mention of a potential class
named BAR, when defining the class named FOO, should give any legitimate
definition for BAR; certainly when you make a forward reference to a
function name, you don't define that funcion; i.e.
(DEFUN FOO (X) (LIST (BAR X X)))
will define FOO, but not define BAR.
Arguing for letting *something* find the forward-referenced class is
the fact that when using the metaobject protocols in an implementation
that supports forward references this way, you will eventually want a
handle on the actual object.
Finally, it must be asked, what is the behaviour of the type system on
non-finalized classes (i.e., classes which have some direct, or even
non-direct, superclass that hasn't been defined yet). Clearly, TYPEP is
moot, since you can't make instances of non-finalized classes. But what
about subtypep? The answer for non-finalized class names probably should
be consistent with the answer for forward-referenced class names.
One possible alternative is simply to say that the class names (or class
objects too) don't become valid type specifiers until the class is fully
defined.
-- Finally, concering your worry: "... will I be offered two modes,
a 'development' mode that supports compilation independence but
generates poor code and a 'production' mode that generates efficient
code but imposes onerous compilation dependencies?"
Well, the *hope* of some of the X3J13 members was that there would be
vendors who would offer you that choice. As far as I know now, no
commercial vendor is actually planning to do so. There was a VERY
interesting research paper presented at the last CLOS workshop (in
conjunction with the 1989 OOPSLA conference in New Orleans) by a guy
from Coherent Thought; they had essentially done the "production" mode
version of CLOS -- at least as far as their application was concerned --
and the overall speed difference was only 25%. Disappointing. That
isn't to say that there isn't *some* benchmark to be found that wouldn't
show a factor of 3 to 5 speedup by this kind of technology, but that
this one naturally occuring application wasn't greatly affected by it.
-- JonL --