CLHS: Issue MAKE-LOAD-FORM-CONFUSION Writeup

#

## Issue MAKE-LOAD-FORM-CONFUSION Writeup

    Status:         Proposal REWRITE (version 8) accepted 12/91
    Issue:          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
            COMPILE-FILE.

       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
     COMPILE-FILE.

    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.

Copyright 1996-2005, LispWorks Ltd. All rights reserved.