[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Issue DEFCONSTANT-NOT-WIRED (V2)
- To: CL-Compiler@SAIL.Stanford.edu
- Subject: Issue DEFCONSTANT-NOT-WIRED (V2)
- From: David N Gray <Gray@DSG.csc.ti.com>
- Date: Thu, 27 Oct 88 19:15:29 CDT
- Sender: GRAY@Kelvin.csc.ti.com
Since no one really liked the proposal DEFCONSTANT-NOT-WIRED:NEW-MACRO,
here is a different approach to the problem that was inspired by
comments from Kent Pitman and Jon L White.
Issue: DEFCONSTANT-NOT-WIRED
References: CLtL pages 68-69
Related issues: Proposals DEFCONSTANT-VALUE:COMPILE-TIME and
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY
Category: ADDITION
Edit history: 9 Oct 1988, V1 by David Gray
27 Oct 1988, V2 by David Gray (new proposal)
Problem description:
As discussed in issue DEFCONSTANT-VALUE, there are two possible views
of what the purpose of DEFCONSTANT is. Proposal
DEFCONSTANT-VALUE:COMPILE-TIME resolves the controversy in favor of
maximizing opportunities for the compiler to substitute the value for
references to the constant.
There may, however, still be cases where one would like to have the
functionality of prohibiting run-time alteration of a value (like
DEFCONSTANT), but have the value computed at load time and not be
wired in (like DEFPARAMETER).
Some people think that this is what DEFPARAMETER should do, but that
would be an incompatible change for other users who have a different
understanding of the meaning of DEFPARAMETER.
Proposal DEFCONSTANT-NOT-WIRED:NEW-DECLARATION
Add a new declaration to the language:
(CONSTANT {varname}+)
This can be used in either PROCLAIM or DECLARE. It specifies that the
variables named are to be treated as constants after their initial
value is established.
For lexical variables, this means that the variable is not permitted
as the destination of a SETQ. (Knowing in advance that the value
won't be altered by a SETQ makes it easier for compilers to perform
certain optimizations.) Implementations are not required to signal an
error if they don't depend on this information.
For special variables, (PROCLAIM '(CONSTANT varname)) means that an
error will be signalled if the variable is used as the destination of
a SETQ or an attempt is made to re-bind it. [Editorial note: this
error behavior is intended to be the same as for DEFCONSTANT, so may
need to be re-worded accordingly.] However, the compiler is not
authorized to "wire in" the value like it does with DEFCONSTANT. This
attribute of the variable is canceled by a DEFVAR or DEFPARAMETER for
the same name, so the PROCLAIM should be executed after the DEFVAR or
DEFPARAMETER that initializes it. An error should be signalled if the
name has not been previously declared to be a special variable. This
proclamation has no effect on a variable declared by DEFCONSTANT
(since it is a subset of what DEFCONSTANT already does).
For a binding of a special variable, an associated declaration
(DECLARE (CONSTANT varname)) declares the programmer's intent that
there be no alteration of the value within the dynamic scope of the
binding. Since it is not practical to detect alteration in compiled
code that is not within the lexical scope of the declaration, this
information is not of much use to a compiler, and signalling of an
error is optional.
[Editorial note: the association of variable names with variables and
the scope of the declaration is intended to be consistent with the
resolution of issue DECLARE-TYPE-FREE, so the wording may need to be
clarified accordingly.]
Examples:
(DEFPARAMETER MEMORY-SIZE (DETERMINE-MEMORY-SIZE))
(PROCLAIM '(CONSTANT MEMORY-SIZE))
computes at load-time the value of parameter MEMORY-SIZE, which can
then be used in subsequent initialization to control the allocation of
data structures for an application. Once these structures are
created, changing this parameter would make no sense and might even
break the program. A DEFCONSTANT is not appropriate because the value
needs to be computed at load time and because the value must not be
wired in to any files compiled later or else those object files could
not be used on another machine with a different memory size.
(LET ((SHORT-PI (COERCE PI 'SHORT-FLOAT)))
(DECLARE (CONSTANT SHORT-PI))
...)
Here the declaration assists a human reader of the program in
recognizing how SHORT-PI is being used, and encourages the compiler to
substitute the value where it is used. (This optimization could be
done without the declaration, but is complicated by the possibility of
alteration within loops or closures.)
Rationale:
This provides the functionality desired by those who are reluctant to
see DEFCONSTANT defined to compute the value at compile time.
This seems to be a cleaner approach than adding an additional defining
macro, and has additional usefulness with lexical variables.
For the purposes that motivated this proposal, it would be simpler to
just support (PROCLAIM '(CONSTANT ...)), but allowing local CONSTANT
declarations seems like such a natural extension that it would seem an
artificial restriction to not permit it.
The error signalling behavior has been specified in such a way as to
minimize the cost to implementors and to avoid slowing down
interpreters with additional bookkeeping.
Current practice:
No implementation of this proposal is known.
The Explorer has a capability equivalent to (PROCLAIM '(CONSTANT ...))
which is used internally for various system parameters, since changing
them could crash the system, but the value should not be wired in to
object files in order to maintain object compatibility between
software releases.
Cost to Implementors:
The minimum requirements are to permit the CONSTANT declaration
(trivial), and to prevent alteration of special variables that have
been PROCLAIMed constant, which should be easy since the mechanism
should already exist for DEFCONSTANTs.
More work would be needed for a compiler to record lexical constant
declarations and report errors for violations. This is not trivial,
but not difficult either.
Cost to Users:
One more little feature to learn. Some user code may need to be
modified as a result of the addition of the symbol CONSTANT to the
LISP package.
Cost of non-adoption:
Continued confusion from the desire to use DEFCONSTANT for situations
that it isn't quite right for, or from expecting DEFPARAMETER to do
more than it does.
Performance impact:
Could help run-time speed by making it easier for compilers to support
value propagation.
Benefits:
Provides a more complete set of options to the user.
Esthetics:
Complicates the language by adding one more declaration, but having
this as a separate feature facilitates giving a clear and simple
definition to DEFCONSTANT and avoids a battle over what DEFPARAMETER
means.
This seems like an elegant solution -- simple syntax with an obvious
meaning.
Discussion:
Version 1 of this issue proposed adding a new macro called
DEFPARAMETER-UNALTERABLE, but no one seemed to like it. (It would
have been equivalent to DEFPARAMETER followed by PROCLAIM CONSTANT.)
It may be desirable to have stricter requirements for signalling
errors if this idea is popular enough for implementors to accept the
cost.