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

issue LOAD-TIME-EVAL



    Date: Thu, 11 Aug 88 14:52:56 MDT
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

    Here are some of my thoughts on cleaning up the existing proposal for
    LOAD-TIME-EVAL:NEW-SPECIAL-FORM.  I haven't yet heard anybody
    objecting to discarding the QUOTED-MAGIC-TOKEN proposal on the same
    issue -- speak now or forever hold your peace! 

Consider this a speech.

       LOAD-TIME-CONSTANT form &optional read-only-p	[Special Form]

       All processing of the FORM is deferred until the expression is
       in the "runtime" environment. Once that environment is available,
       FORM is evaluated in the null lexical environment and the result
       is both returned and saved for immediate access by the program
       on subsequent evaluations.

       In the interpreter, the FORM may be evaluated during pre-processing
       (if any) or dynamically when the LOAD-TIME-CONSTANT is first seen
       (in a non-pre-processing implementation). If the same LOAD-TIME-CONSTANT
       expression is later seen again by the interpreter, the previously
       obtained result is immediately retrieved and returned as the result
       of evaluating the object; no re-evaluation occurs.

I don't know what "all processing" means.  For example, does this forbid
the compiler from performing optimizations that it might perform on other
expressions in a file being compiled?  Or does it just mean evaluation?

    There is some possible confusion over what "the same LOAD-TIME-CONSTANT 
    expression" means; in particular, is it the entire LOAD-TIME-CONSTANT 
    form or the evaluable form inside of it that is compared?  What predicate 
    is used to compare them -- EQ or EQUAL?  And, is it the *reference* to
    the LOAD-TIME-CONSTANT form that is checked, or the form itself -- 
    something which makes a big difference given that there may be multiple
    references to the same code fragment?  In other words, is it a legitimate 
    implementation technique for the interpreter to destructively bash the 
    list (LOAD-TIME-EVAL <foo>) into (QUOTE <what-foo-evaluates-to>)?
    
All of these issues would be avoided by using something more compatible
with the way the #, reader syntax works.  I don't recall a quoted-magic-token
proposal (perhaps I have not read it yet), but a technique where the
primitive offered is a way to create a data object that can be used
only inside a quoted constant would avoid all these problems, as long
as we know what "the same" means for quoted constants, and I think we do.

The primitive should be a function, not a special form, and should take
two arguments, a form and an optional macroexpansion environment.  The
form is either evaluated immediately in the null lexical environment
(when not compiling to a file) and its value returned, or encapsulated
in a magic compiler/loader recognizable object (when compiling to a file)
and evaluated in the null lexical environment later when the file is loaded.
The purpose of the macroexpansion environment argument is to distinguish
whether the quoted constant being constructed is destined for the current
environment or for a compiler output file [I believe this is a pending
issue, unless it's been resolved recently.]

I don't believe in the read-only-p argument, since I believe all constants
are inherently read-only, and that anyone using constants to simulate
variables (as some Interlisp programs do) should be using variables instead.

(defmacro load-time-constant (form &environment env)
  `(quote ,(sharp-comma form env)))

       If the LOAD-TIME-CONSTANT expression is seen by the file compiler
       (eg, COMPILE-FILE), the compiler arranges for all semantic processing
       of FORM (including macro expansion) to occur at load time in a null
       lexical environment (independent of whether any value has been cached
       for interpreter use). At runtime, the result of that evaluation will
       be treated as an immediate quantity; no re-evaluation occurs.

    Doing macro expansion in a null lexical environment makes this behave
    more like (EVAL-WHEN (COMPILE) ...) than (EVAL-WHEN (LOAD) ...).  
    
       If a LOAD-TIME-CONSTANT expression is seen by the runtime compiler
       (eg, COMPILE), the compiler checks for a cached value which may have
       been produced by the interpreter. If one is found, it is used. If no
       such value is found, the runtime compiler will evaluate the FORM in
       a null lexical environment and use that value.  The value used will be
       treated as an immediate quantity in the code which is produced; no
       re-evaluation occurs.   

    Is the compiler supposed to cache the value of FORM for later use by
    the interpreter?  Again, this is a concern if there are multiple
    references to the same expression.

The above couple paragraphs seem to be examples of the confusion rampant
in Common Lisp, between two meanings of "the compiler."  One is "a program
that makes programs run faster by converting them to machine instructions",
the other is "a program that makes files load faster by converting them to
a binary format."  While these are often used together, only the second
form of compiler is relevant to #,.  I think understanding this distinction
ought to clear things up.