[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: LOAD-TIME-EVAL
- To: Gray@DSG.csc.ti.com
- Subject: Re: LOAD-TIME-EVAL
- From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
- Date: Fri, 9 Sep 88 12:04 EDT
- Cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, Cl-Compiler@SAIL.Stanford.EDU
- In-reply-to: <2798810739-416955@Kelvin>
Date: Fri, 9 Sep 88 10:25:39 CDT
From: David N Gray <Gray@DSG.csc.ti.com>
> Anyone who asks that #, be flushed is, in effect, asking me to write this kind
> of stuff.
Wait a minute; I was _not_ advocating flushing #, ;
Yes, but some people have. My reply to you was as much a reply to a lot of preceding
mail.
I _was_ saying that the READ-ONLY-P argument was not a good idea. What I was
objecting to was the notion of evaluating a "constant" at load time and then
destructively modifying that value later; I don't see that any of your examples
do that.
The full text of the system I'm alluding to in the second example does do
side-effects. They are of two kinds:
- ADJUST-ARRAY is done on one of the arrays which is a load time constant
so that when new classes (or whatever) are added, it can allocate space
in the same table to accomodate them. [This is not a problem because
the old load-time constants never look at the new rows.]
- If the slot mappings change, it fills the table with new values. [This
is a major problem because if the old load-time constants have gotten
separated from the new load-time constants, or if all load-time constants
are read-only, I cannot update the table.
In the rare cases where there is a valid need to do something like that,
the approach shown by Dalton seems sufficient.
Dalton's approach is clever, but is not adequate for a number of reasons in
any serious application. Here are a few that come quickly to mind ...
- I'm not convinced that the spec for either the compiler or GENSYM is
written in a constrained enough way to make me believe that all compilers
will correctly handle the writing out and re-loading of that GENSYM. Some
compilers I've known would either intern the gensym later, or would get
the two gensyms become un-EQ. We'd need a serious tightening up of the
contract of the compiler to even make this plausible to me. [Especially
if that GENSYM can occur in other functions or files and must be somehow
linked up with others which were EQ at macro-expansion time, the problem
seems nearly intractable to me.]
- No serious CLOS implementation (or other class-system or large-scale
system using zillions of these) could be built on it. I could easily imagine
this construct occurring many thousands of times, in a large program,
wasting tens or hundreds of thousands of bytes of space gratuitously.
It would gratuitously waste a ton of symbol space to no good end and users
would complain mightily. The only response would be "Well, I asked for a
more space-efficient way to do this, but people on CL-Compiler said it
was gratuitous and that this was the best I should be able to do."
- It incurs runtime overhead when load-time overhead is all that's required.
This means if the initial computation is very expensive, it can't be done
when dumping an application prior to delivery. It must be repeatedly
incurred at runtime.
- It isn't adequately synchronized with the running of the program. It may
be that running the program will violate the initial state. This is a
general problem that interpreters have and not one you can guard against
completely, but it's one that I think you're best to guard against where
you can. One of the worst things is to get a function
(DEFUN FOO (X) (IF X (LOAD-TIME-CONSTANT (Z)) (LOAD-TIME-CONSTANT (Z))))
which can return two different answers depending on whether X is NIL or T.
[Supposing that (Z) is a state-reader and not a state-modifier, etc.
but that (Z) is dependent on some global state which usually doesn't
but might change -- eg, function definitions themselves.]
If you don't compute all these things at load time, you risk that the
state of the system will change radically between the time the first (Z)
and the second (Z) are called. Doing real load-time evaluation reduces
this sort of risk and even if it doesn't guarantee solidity, it enhances
the chances of it.
- It doesn't deal with issues of caching for `equal expressions', etc.
[That's a trivial deal; it could easily be made to. But I just thought
I'd mention it.]