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

Re: LOAD-TIME-EVAL



    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.]