[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
- To: firstname.lastname@example.org, email@example.com
- Subject: proposal LOAD-TIME-EVAL:REVISED-NEW-SPECIAL-FORM
- From: firstname.lastname@example.org (Sandra J Loosemore)
- Date: Mon, 19 Sep 88 14:06:15 MDT
- Cc: email@example.com
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.
Add a new special form, LOAD-TIME-VALUE, which has the following
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
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
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
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.