[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Issue: LOAD-OBJECTS (Version 2)
...
The creation form for an object is always evaluated before the
initialization form for that object. When either the creation form or
the initialization form references other objects of user-defined types
that have not been referenced earlier in the COMPILE-FILE, the
compiler collects all of the creation forms together and collects all
of the initialization forms together. All of the creation forms are
evaluated before any of the initialization forms. The order of
evaluation of the creation forms is unspecified except when the
ordering is forced by data dependencies. The order of evaluation of
the initialization forms is unspecified.
...
Why does the proposal restrict the evaluation initialization forms to
such a late time? Data dependencies would allow an object X's
initialization form to be executed any time after X's creation form had
finished. Is there a reason to be more strict? I can't think of one,
but if there is one, it should be stated on the rationale.
Actually, it would be better (and no more difficult, it seems to me) to
be strict in the other direction: Objects should be initialized as early
as possible, and hence at a deterministic time. This would allow nodes
in non-circular structures to be built out of fully initialized subparts,
which is clearly something an application could need.
Here's what your paragraph would look like, given that point:
The creation form for an object X is always fully evaluated before the
initialization form for that object. This evaluation includes the
evaluation of the creation form of any user-defined object Y contained
in X's creation form, and will also include the evaluation of Y's
initialization form, if X and Y are not part of a circular chain of
initialization forms. Any circular substructures of X will be fully
initialized. Initialization forms of circular structures are
evaluated in an implementation-defined order, subject to the previous
restrictions. These rules are intended to ensure that initialization
follows creation as quickly as possible, subject to data flow.
Under these rules, noncircular data structures will be treated as if
all the initialization forms will immediately follow the creation
forms this way:
(eval `(let ((obj ,<creation-form>))
,(subst 'obj <original-object> <initialization-form>)
obj))
Furthermore, circular sub-structures will not impair the timely
initialization of non-circular containing structures. Such guarantees
will give programmers a sense of security in breaking out as much
processing as possible into the initialization form.
If this point of view is not adopted, a laissez-faire position is probably
better, and I think your paragraph above could be deleted, or rewritten thus:
The creation form for an object is always fully evaluated before the
initialization form for that object. This evaluation includes the
evaluation of creation forms of any user-defined objects contained in
the creation form, and may or may not include the evaluation of
initialization forms. However, when a "top-level object" is loaded,
all creation and initialization forms of that object must be fully
evaluated before any further loading actions are taken. These rules
are intended to allow implementations a high degree of freedom in
ordering the evaluation of creation and initialization forms, subject
to the requirements of data flow.
This paragraph needs to define the the specially-treated "top-level object",
which seems to be a concept implicit in your original paragraph. But I'd
rather see my first point adopted, and be done with top-level objects.
-- John