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

proposal LOAD-TIME-EVAL:REVISED-NEW-SPECIAL-FORM



Since the cleanup committee is expecting us to do something on this
issue promptly, I've gone ahead with the sketch for the new proposal
on this issue that I started on last week.  Not having heard anything
back from my last request for comments (are all of you compiler people
asleep?), I've rather arbitrarily decided upon allowing the
interpreter to perform multiple evaluations, and warning users that
they can get into trouble by performing destructive operations.

Because the writeup on this issue is already so long, I've only
included the most relevant parts here.  If I hear some favorable
feedback on what I've got so far, I'll finish it up the rest of it.
Otherwise, I will turn the issue back over to Pitman and the cleanup
committee in the hopes that they will be able to make more progress on
it than we have.

-Sandra



Proposal (LOAD-TIME-EVAL:REVISED-NEW-SPECIAL-FORM):
    
 Add a new special form, LOAD-TIME-VALUE, which has the following
 contract:

   LOAD-TIME-VALUE 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 returned; the result may also be saved for immediate access by 
   the program on subsequent evaluations.

   LOAD-TIME-VALUE is, in effect, a promise by the user that multiple
   evaluations of <form> will return values that are semantically 
   equivalent (although not necessary EQ).

   In the interpreter, (LOAD-TIME-VALUE <form>) is equivalent to
   (VALUES (EVAL (QUOTE <form>))).  However, it is permissible for
   an implementation to perform the evaluation of <form> only once for
   each reference to the surrounding LOAD-TIME-VALUE expression and to
   cache that value for subsequent use; this may be done by a 
   preprocessor, for example.

   If a LOAD-TIME-VALUE expression appears within a function compiled
   with COMPILE, the compiler may either evaluate the <form> or use
   a previously cached value.  It is guaranteed that the <form> will
   not be evaluated again at runtime; instead, the result of the
   compile-time evaluation is treated as an immediate quantity in the
   compiled code.

   If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
   arranges for all semantic processing of <form> (including macro
   expansion) to occur at load time in a null lexical environment.  It
   is guaranteed that the evaluation of <form> will take place only once
   when the file is loaded, but the order of evaluation with respect to
   the "evaluation" of top-level forms in the file is unspecified.

   Note that, in interpreted code, there is no guarantee as to when
   evaluation of <form> will take place, or the number of times the
   evaluation will be performed.  This is intentionally similar to the
   freedom which implementations are given for when macros are expanded
   in interpreted code.

   Implementations must guarantee that each reference to a LOAD-TIME-VALUE 
   expression within a form to be evaluated results in at least one 
   evaluation of <form>.  It is not permissible to "collapse" either 
   multiple references to the same (EQ) LOAD-TIME-VALUE expression or 
   EQUAL expressions.  Note that, in the case of a LOAD-TIME-VALUE form
   appearing in a quoted expression passed to EVAL, each call to EVAL must 
   result in a new evaluation of <form>.  For example,
     (DEFVAR X 0)
     (DEFUN FOO () (EVAL '(LOAD-TIME-VALUE (INCF X))))
   is guaranteed to increment X each time FOO is called, while
     (DEFUN FOO () (LOAD-TIME-VALUE (INCF X)))
   may cause X to be evaluated only once.

   The READ-ONLY-P argument designates whether the result can be considered
   read-only constant. If NIL, the result must be considered ordinary,
   modifiable data. If T, the result is a read-only quantity which may, as
   appropriate, be copied into read-only space and/or shared with other
   programs. (Because this is a special form, this argument is -not- evaluated
   and only the literal symbols T and NIL are permitted.)

   Note that, since successive evaluations of the same LOAD-TIME-VALUE
   expression may or may not result in an evaluation which returns a 
   "fresh" object, users cannot rely upon either the persistence or
   absence of destructive side-effects.  In such cases, it is safest to
   explicitly initialize the object returned by LOAD-TIME-VALUE.

 Make #,exp be equivalent to (LOAD-TIME-VALUE exp T). As such, it
 would -always- appear in a for-evaluation position, and never inside quoted
 structure.

 Rationale:
    
   By making the description of LOAD-TIME-VALUE defined as a special
   form, we eliminate the need for it to take an environment argument.

   By making #, agree with LOAD-TIME-VALUE in terms of where it may be
   used, we simplify the description of the resulting language.

   As discussed in more detail elsewhere in this proposal, the #, syntax
   is currently only reliably useful -inside- quoted structure, but this
   is unnecessarily complicated for most known uses. Since this proposal
   suggests a meaning for #, only -outside- quoted structure, it is an
   incompatible change (though not one that would necessarily require
   vendors to immediately remove support for existing code).

   Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
   evaluated more than once makes it much simpler to implement in
   interpreters which do not perform a preprocessing code walk.  It also
   makes the rules for the time of its processing analogous to those
   for macro expansion.

   The prohibition against collapsing of shared or EQUAL LOAD-TIME-VALUE
   expressions prevents problems that could result by performing destructive
   side-effects on a value that is referenced in more than one place.


 Cost to Implementors:

   This is an incompatible change to the program interface.
   The cost is not trivial, but is not particularly high.
   Most of the "hard" substrate required to support this proposal
   probably already exist; in most cases, what needs to change is
   only the way in which the substrate is presented to the
   programmer.

   Some code-walkers would have to be taught about this new
   special form. Such changes would likely be trivial.

   For implementations that do not use a preprocessor in the interpreter,
   the simplest technique for implementing LOAD-TIME-VALUE would be to
   always evaluate <form> without caching the value.  Implementations
   that do use a preprocessing code walk could be extended to do the
   evaluation at the same time they do macro expansion.

-------