[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Standard-objects in quoted constants



Thanks for doing this Chris, I'm glad you did this exercise.

    Date: Mon, 14 Nov 88 11:54:29 PST
    From: cperdue@Sun.COM (Cris Perdue)
    We are also in the process of requesting information on current
    practice from implementors.

Here is some information about a Lisp which shall remain nameless.

    - References to symbols are left for load-time resolution.

Furthermore:  The symbol is resolved by lookup in its home package.  If
the current package is not the same as the home package, and the symbol
is not EXTERNAL, then an error is signaled.  (I.e. it should have the
same behaviour as print/read).

This is the behaviour in the implementation I am describing, and I also
believe this should be the required behaviour.  I'm sure someone can
state it better than I just did, however.  (I recall Moon doing so in
the past).

    - Aggregate objects are traversed and their components are also
      recorded.

I think this serves as a definition of the term "aggregate objects", and
not as a guiding principle.  For example, it is an arbitrary decision
not to dump symbol's values and plists.

    - Numbers and characters, i.e. objects that must be compared with EQL
      rather than EQ, are not aggregate in the sense being discussed here.
      They may appear in constants, and numbers and characters appearing
      in constants have the same requirements on their behavior as numbers
      and characters in any other context.

EQLness is preserved in the implementation being described, uniformly
among all objects.

    For aggregate objects there must be some policy on supporting
    circular structures and otherwise shared structures.  That is not
    specified here.

Circular structures are fully supported in the list I am describing.  I
do think this should be the standard, but a number of Lisps, including
Symbolics, and I believe TI, would have to be changed, possibly
significantly.  I suspect all would agree it's the right thing, but I
don't know about willingness to comply.

    Each aggregate object has certain Basic Attributes (B.A.'s?)
    These are recorded as the constant is compiled and they are also
    traversed.

    Symbol	     No symbol is a constant in the sense considered here, but
		 references to symbols are permitted in any constant.

How is it not a constant?  (I'm sure this is just a matter of
terminology).  Or do you mean it's not an agregate object (i.e. not
traversed)?  Or that it is not made immutable?  I think we'd all agree
on the latter two questions...

    Array	     All elements, fill pointer existence,
		 fill pointer value if present,
		 dimensions, element-type, adjustable-array-p, displaced-to,
		 displaced-index-offset

All elements up to fill pointer.  A simple array is dumped, of the same
element-type.

The issue here is what is the MEANING of an array CONSTANT with a fill
pointer?  An array CONSTANT is not a dynamic datastructure.  Fill
pointers, adjustable-array-p, displaced-to, etc. are merely artifacts of
how that array of data is CREATED, not how it may be used when viewed as
a constant.  Since correctly-written programs don't bash their
constants, they won't notice if the array has a fill pointer, or is
displaced, or adjustable.  So there's no point in dumping them.

Note that this is the same behaviour as PRINT/READ, with the one
exception of the ARRAY-ELEMENT-TYPE.

    Structure    Slot values, name of structure type

This isn't good enough, but it's OK for a default.  In general, to
handle the full semantics of possible structures, properly handling
circularity, a protocol is needed where first the loader creates an
object of the right size and then passes it off to a named user function
which fills in the object, performing any necessary initialization, such
as registry in a hash table, etc.

    Hash-table   Keys and values.  The table's test is of course unchanged also.
		 In an EQ hash table, keys that are not EQ must not be
		 coalesced.  In an EQL hash table, keys that are not EQL
		 must not be coalesced (or made EQL).  (These are
		 exceptions to the general rule that constants may be
		 coalesced.)  

Er, but what if they were coalesced elsewhere in the program?  How can
you know that now you have to dump a copy?  OK, so you have to maintain
two tables, recording each EQ entry, and the (non-unique) index found
for it.  But if you were expecting it to be EQ to the same EQ constant
elsewhere in the program, you'll be supprised to learn that it's no
longer EQ.  So why bother?  And what about subelements of EQ objects in
EQ hash tables?  If I have ((A)) and the CAR of that list both as keys,
do they have to remain EQ?

I think you're either better off saying no coalescence, or saying that
EQ hash tables do not preserve EQUAL (or whatever coalescense predicate
you choose) entries.

			      In short, hash table keys that are initially
		 distinct must remain distinct across the process of
		 file-compilation and loading.

I like this principle.  I used to be a fan of coalescence, but the
difficulty of unambiguously specifying issues like this has led me to no
longer be a fan.

The mystery lisp does not currently coalesce non-EQ constants.

    Readtable    Character syntax type for each character in the table;
		 function for each readmacro character, mappings for
		 dispatch macros; terminating or nonterminating for each
		 readmacro.

(error "Can't dump readtables yet.")

This sounds right.

    Pathname     Each pathname component

Right.

    Package, Stream
		 It is an error for a package, stream, or compiled-function
		 to appear ina compiled constant, but the
		 language may be extended in the future to support certain
		 cases.

Packages are dumped by name.  It is an error to reference a package
which is not previously defined in the loading environment.

    Random-state
		 Random-states have no basic attributes, and only the
		 "random" operation applies to them (other than PRINT).
		 Let us say that two random-states are functionally
		 equivalent if applying "random" to them repeatedly always
		 produces the same pseudo-random numbers.  Since compiled
		 constants may become immutable, applying "random" to a
		 compiled-constant random-state is an error.  However,
		 all copies made via make-random-state must be
		 functionally equivalent and functionally equivalent to
		 the one that appeared in the source code.

Right.  The point you make about immutability is important, too.

    Function     Function constants that are not compiled-functions are
		 permitted in compiled constants.

Um:

(defun foo (x) #'(lambda () x))
(typep (foo 3) 'compiled-function) => ?

Is this required to return T?  It doesn't on a Symbolics 3650.

The lisp being described does not dump objects of type FUNCTION,
currently.  If it is extended to do so, it will probably dump compiled
functions.


    This appears to be a reasonable approximation to what is done by the
    Franz and Lucid implementations.  The Explorer apparently does not
    currently guarantee retention of displaced-to and
    displaced-index-offset attributes.

The Explorer is correct.  In the Explorer, also, arrays can be displaced
to a physical address, which is obviously an absurd thing to put into a
compiled file.

    Adoption cost:

    Not known.  Probably moderate.  The cost would be to implementors
    rather than users since this part of the language is currently
    underspecified.

I agree the cost is moderate, but there will probably be a cost to
some users as well as implementors.  However, such usage would not have
been portable, and portable usage will now be possible.

    Conversion cost:

    Nil.  Less than the cost of leaving things unspecified.

Nah, we can argue up the cost of specification if we TRY.