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

Issue DEFCONSTANT-NOT-WIRED (V2)



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.