[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
- Aggregate objects are traversed and their components are also
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
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
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,
All elements up to fill pointer. A simple array is dumped, of the same
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
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
(error "Can't dump readtables yet.")
This sounds right.
Pathname Each pathname component
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
Packages are dumped by name. It is an error to reference a package
which is not previously defined in the loading environment.
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.
(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
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
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
Not known. Probably moderate. The cost would be to implementors
rather than users since this part of the language is currently
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.
Nil. Less than the cost of leaving things unspecified.
Nah, we can argue up the cost of specification if we TRY.