Status: Proposal REWRITE (version 8) accepted 12/91Issue: MAKE-LOAD-FORM-CONFUSION
Reference: Draft 9.126, MAKE-LOAD-FORM (p.9-30)
Proposal LOAD-OBJECTS:MAKE-LOAD-FORM (Version 4)
Proposal CONSTANT-COMPILABLE-TYPES:SPECIFY (Version 10)
Proposal COMPILE-ENVIRONMENT-CONSISTANCE:CLARIFY (Version 6)
Issue CONFORMING-METHODS
Category: Change
Edit History: Version 1, 7/19/91, Kim Barrett
Version 2, 7/25/91, Kim Barrett
Version 3, 8/2/91, Kim Barrett
Version 4, 8/18/91, Kim Barrett
Version 5, 9/3/91, Kim Barrett (dangling "conforming method")
Version 6, 9/18/91, Kim Barrett (proposal REWRITE)
Version 7, 9/25/91, Kim Barrett
(proposal REWRITE-WITH-POSITIONALS, update Discussion &etc,
change "same (EQ)" to "\term{same}", add "Notes")
Version 8, 9/25/91, Kim Barrett (Moon's comments, change bars)
Problem Description:
The last paragraph of the MAKE-LOAD-FORM proposal inadvertently forbids
implementations from providing methods for MAKE-LOAD-FORM which are applicable
to instances with metaclass STANDARD-CLASS or STRUCTURE-CLASS.
There was discussion about specifying that class metaobjects encountered as
compiled constants should be handled by looking up the class by name at load
time, but it appears that several mutually referencing issues may have all
assumed that this would be dealt with by one of the others, with the result
that nothing was actually specified for this situation.
MAKE-LOAD-FORM and MAKE-LOAD-FORM-SAVING-SLOTS are functions that deal with
forms, but violate the general principle that any function that manipulates
forms must have access to the environment in which those forms are to be
processed.
Proposal (MAKE-LOAD-FORM-CONFUSION:REWRITE):
[Note: Lines beginning with "-n-" (where n is an integer) are not part of this
proposal. These lines were taken verbatim from the passed LOAD-OBJECTS
proposal, and are present only as an aid to understanding some of the changes
being made by this proposal by presenting both the original text and the
corresponding rewritten description side by side. Lines beginning with "+n+"
are part of the proposal, and are the proposed replacements for the
corresponding "-n-" text. However, the absence of these change markers should
not be taken to imply that the unmarked text is the same as the LOAD-OBJECTS
proposal or Draft 9.126.]
1. Replace the specification of MAKE-LOAD-FORM with the following:
MAKE-LOAD-FORM Standard Generic Function
Syntax:
MAKE-LOAD-FORM object &optional environment
Method Signatures:
make-load-form (object standard-object) &optional environment
make-load-form (object structure-object) &optional environment
make-load-form (object condition) &optional environment
make-load-form (object class) &optional environment
Arguments:
object -- an object.
environment -- an environment object.
Values:
Value 1: Creation form.
Value 2: Initialization form or not returned.
Description:
The generic function MAKE-LOAD-FORM creates and returns one or two
forms, a creation form and an initialization form, that enable LOAD to
construct an object equivalent to \arg{object}. \arg{Environment} is
the environment in which the forms will be processed.
-1- COMPILE-FILE calls MAKE-LOAD-FORM on any object that is referenced as
-1- a constant or as a self-evaluating form, if the object's metaclass is
-1- STANDARD-CLASS, STRUCTURE-CLASS, any user-defined metaclass (not a
-1- subclass of BUILT-IN-CLASS), or any of a possibly-empty
-1- implementation-defined list of other metaclasses. COMPILE-FILE will
-1- only call MAKE-LOAD-FORM once for any given object (compared with EQ)
-1- within a single file.
+1+ COMPILE-FILE calls MAKE-LOAD-FORM on any object that is referenced as a
+1+ constant or as a self-evaluating form, if the object is a generalized
+1+ instance of STANDARD-OBJECT, STRUCTURE-OBJECT, CONDITION, or any of a
+1+ possibly empty implementation dependent list of other classes.
+1+ COMPILE-FILE will only call MAKE-LOAD-FORM once for the \term{same}
+1+ object within a single file.
-2- It is valid for user programs to call MAKE-LOAD-FORM in other
-2- circumstances, providing the argument's metaclass is not BUILT-IN-CLASS
-2- or a subclass of BUILT-IN-CLASS.
+2+ Programmers may call MAKE-LOAD-FORM directly, providing \arg{object} is
+2+ a generalized instance of one of the explicitly named classes listed
+2+ previously.
-3- MAKE-LOAD-FORM of an object of metaclass STANDARD-CLASS or
-3- STRUCTURE-CLASS for which no user-defined method is applicable signals
-3- an error. It is valid to implement this either by defining default
-3- methods on STANDARD-OBJECT and STRUCTURE-OBJECT that signal an error
-3- or by having no applicable method for those classes.
+3+ The methods specialized on STANDARD-OBJECT, STRUCTURE-OBJECT, and
+3+ CONDITION all signal an error of type ERROR.
The method specialized on CLASS returns a creation form using the name
of the class if the class has a proper name in \arg{environment},
signaling an error of type ERROR if it does not have a proper name.
Evaluation of the creation form uses the name to find the class with
that name, as if by calling FIND-CLASS. If a class with that name has
not been defined, then a class may be computed in an implementation
defined manner. If a class cannot be returned as the result of
evaluating the creation form, then an error of type ERROR is signaled.
Implementations may provide additional methods specialized on system
classes. It is implementation dependent whether calling MAKE-LOAD-FORM
on a generalized instance of a \term{system class} signals an error or
returns creation and initialization forms.
Both implementations and programs may define additional
\term{conforming methods} to extend the behavior of MAKE-LOAD-FORM.
The creation form is a form that, when evaluated at \term{load time},
should return an object that is equivalent to \arg{object}. The exact
meaning of ``equivalent'' depends on the type of object and is up to
the programmer who defines a method for MAKE-LOAD-FORM. See ``What can
appear as a constant'' and ``Similarity as constants''.
The initialization form is a form that, when evaluatated at \term{load
time}, should perform further initialization of the object. The value
returned by the initialization form is ignored. If MAKE-LOAD-FORM
returns only one value, the initialization form is NIL, which has no
effect. If \arg{object} appears as a constant in the initialization
form, at \term{load time} it will be replaced by the equivalent object
constructed by the creation form; this is how the further
initialization gains access to the object.
-4- Both the creation form and the initialization form can contain
-4- references to objects of user-defined types (defined precisely below).
+4+ Both the creation and initialization forms may contain references to
+4+ objects of any type which can be processed as a constant by
+4+ COMPILE-FILE. However, there must not be any circular dependencies in
creation forms. An example of a circular dependency is when the
creation form for the object X contains a reference to the object Y,
and the creation form for the object Y contains a reference to the
object X. Initialization forms are not subject to any restriction
against circular dependencies, which is the reason that initialization
forms exist. See the example of circular data structures below.
-5- The creation form for an object is always evaluated before the
-5- initialization form for that object. When either the creation form or
-5- the initialization form references other objects of user-defined types
-5- that have not been referenced earlier in the COMPILE-FILE, the
-5- compiler collects all of the creation and initialization forms. Each
-5- initialization form is evaluated as soon as possible after its
-5- creation form, as determined by data flow. If the initialization form
-5- for an object does not reference any other objects of user-defined
-5- types that have not been referenced earlier in the COMPILE-FILE, the
-5- initialization form is evaluated immediately after the creation form.
-5- If a creation or initialization form F references other objects of
-5- user-defined types that have not been referenced earlier in the
-5- COMPILE-FILE, the creation forms for those other objects are evaluated
-5- before F, and the initialization forms for those other objects are
-5- also evaluated before F whenever they do not depend on the object
-5- created or initialized by F. Where the above rules do not uniquely
-5- determine an order of evaluation, which of the possible orders of
-5- evaluation is chosen is unspecified.
+5+ The creation form for an object is always evaluated before the
+5+ initialization form for that object. When either the creation form or
+5+ the initialization form references other objects that have not been
+5+ referenced earlier in the file being compiled, the compiler ensures
+5+ that all of the referenced objects have been created before evaluating
+5+ the referencing form. When the referenced object is of a type which
+5+ COMPILE-FILE processes using MAKE-LOAD-FORM, this involves evaluating
+5+ the creation form returned for it. (This is the reason for the
+5+ prohibition against circular references among creation forms).
+5+
+5+ Each initialization form is evaluated as soon as possible after its
+5+ associated creation form, as determined by data flow. If the
+5+ initialization form for an object does not reference any other objects
+5+ not referenced earlier in the file and processed by COMPILE-FILE using
+5+ MAKE-LOAD-FORM, the initialization form is evaluated immediately after
+5+ the creation form. If a creation or initialization form F does contain
+5+ references to such objects, the creation forms for those other objects
+5+ are evaluated before F, and the initialization forms for those other
+5+ objects are also evaluated before F whenever they do not depend on the
+5+ object created or initialized by F. Where these rules do not uniquely
+5+ determine an order of evaluation between two creation/initialization
+5+ forms, the order of evaluation is unspecified.
While these creation and initialization forms are being evaluated, the
objects are possibly in an uninitialized state, analogous to the state
of an object between the time it has been created by ALLOCATE-INSTANCE
and it has been processed fully by INITIALIZE-INSTANCE. Programmers
writing methods for MAKE-LOAD-FORM must take care in manipulating
objects not to depend on components that have not yet been initialized.
It is implementation dependent whether LOAD calls EVAL on the forms or
does some other operation that has an equivalent effect. For example,
the forms might be translated into different but equivalent forms and
then evaluated, they might be compiled and the resulting functions
called by LOAD, or they might be interpreted by a special-purpose
interpreter different from EVAL. All that is required is that the
effect be equivalent to evaluating the forms.
Examples:
{use existing examples}
Affected By:
None.
Exceptional Situations:
Certain methods signal an error when called, indicating that
\arg{object} cannot be used as a constant in code being processed by
See Also:
COMPILE-FILE, MAKE-LOAD-FORM-SAVING-SLOTS, ``Compilation'',
``Evaluation''.
Notes:
Some implementations may provide facilities for defining new subclasses
of classes which are specified as \term{system classes} by this
standard (some likely candidates include GENERIC-FUNCTION, METHOD, and
STREAM). Such implementations should document how COMPILE-FILE treats
instances of such classes when encountered as constants, and should
document any relevant methods for MAKE-LOAD-FORM.
2. Change the syntax of MAKE-LOAD-FORM-SAVING-SLOTS to
MAKE-LOAD-FORM-SAVING-SLOTS object &key :slot-names :environment
\arg{Environment} is an environment object, and is the environment in which
the forms will be processed.
Proposal (MAKE-LOAD-FORM-CONFUSION:REWRITE-WITH-POSITIONALS):
Same as MAKE-LOAD-FORM-CONFUSION:REWRITE, except that the syntax for
MAKE-LOAD-FORM-SAVING-SLOTS is changed to
MAKE-LOAD-FORM-SAVING-SLOTS object &optional slot-names environment
Editorial Impact:
A new version of MAKE-LOAD-FORM must be integrated into the document. It is
intended that this be a matter of making stylistic edits, formatting, and
getting fonts right for defined names, glossary terms, and such.
Small changes to MAKE-LOAD-FORM-SAVING-SLOTS.
Possibly some small changes to the description of constant processing by
Rationale:
Adding optional environment arguments to these functions provides them with
access to the environment in which the forms to be returned will be processed
by COMPILE-FILE.
The rewrite attempts to fix the problem that the original specification of
MAKE-LOAD-FORM said something much stronger than was perhaps actually
intended, while still providing programmers with some guarantees about the
behavior of MAKE-LOAD-FORM when applied to instances of portable classes.
The intent is that programmers may define portable classes with the knowledge
that these classes will not be unintentionally inheriting supposedly useful
but actually inadequate methods for MAKE-LOAD-FORM provided by the
implementation, while still permitting COMPILE-FILE to use MAKE-LOAD-FORM for
handling instances of classes which are specified as possibly being built in
classes and for instances of additional implementation specific classes.
Adding a method signature for CLASS fills the gap mentioned in the problem
description. Some portions of the mechanism for performing the name to class
lookup are implementation defined in order to permit extensions (such as
forward referenced classes). This method is needed because class metaobjects
are valid type specifiers and so may be expected to appear directly in code to
be compiled.
Current Practice:
Lucid plans (in a future release which includes MAKE-LOAD-FORM) to provide the
method signature MAKE-LOAD-FORM (object CLASS), which will return a form that
looks up the class by name, returning a forward referenced class if necessary.
Symbolics removed the method MAKE-LOAD-FORM (object CLASS) from their current
development system, both because of technical issues related to extensions and
because of a belief that there were unresolved semantic issues. This proposal
attempts to deal with those issues.
Presumably nobody has yet given MAKE-LOAD-FORM an optional second argument.
Cost to Users and Implementors:
All existing methods for MAKE-LOAD-FORM will have to be modified to accept the
optional second argument. Some methods might need to be modified to use the
argument, rather than simply ignoring it. Probably the number of methods
involved is small, and both implementors and users will presumably be alerted
to unmodified definitions because of lambda-list congruency failures.
Calls to MAKE-LOAD-FORM-SAVING-SLOTS will need to be examined to determine
whether there is a missing environment argument that needs to be supplied, and
figure out where that environment is supposed to come from. Since most calls
to this function are likely to be in MAKE-LOAD-FORM methods, this is probably
going to be easy in virtually every case.
Discussion:
There was significant divergence of opinion regarding the treatment of class
metaobjects as compiled constants. Some discussion revolved around the issue
of whether the name to class mapping was sufficiently dependable to make
dumping by loadtime name lookup a reasonable choice, and whether this facility
was needed at all. The principal point of debate was the question of what to
do at loadtime when FIND-CLASS doesn't find a class. The passage from
COMPILE-ENVIRONMENT-CONSISTANCY regarding classes defined with DEFCLASS bears
on both of these questions. The current description is a compromise whose
intent is to permit but not require certain kinds of extensions, while
providing users with confidence that something well defined will happen if
this situation (which COMPILE-ENVIRONMENT-CONSISTANCY can be interpreted as
saying is an error) occurs.
Moon, regarding environment information
As I keep saying over and over (although I guess I must not have been
listening to myself when I first proposed make-load-form!), no form has any
meaning without an accompanying environment.
JonL, in response to the question
Will users complain if we don't add the ability to fasdump named class
objects to the language?
Already have. In droves. Probably because class-objects are written into
the language as first-class type-specifiers, and are being incorporated into
programs (as constants) with impunity.
Moon and Barrett both prefer proposal REWRITE over REWRITE-WITH-POSITIONALS.