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

constant folding/smashing



re: My point is that in the form
       (SETF (SYMBOL-VALUE (QUOTE X)) 1)
    the quoted object is no more or less "constant" than in the form
       (SETF (FIRST (QUOTE (A B C))) 1)
    So why does QUOTE make the components of the list (1 2 3)
    unmodifiable but not the components of X?

Because the semantic model of symbols doesn't consider them to have 
modifiable components; they are "atomic".  In fact, several implementations 
I'm familiar do a "spaghetti-stack" lookup for the SYMBOL-VALUE function  -- 
not a structure-component fetch.  And there have been serious suggestions for
flushing the symbol-plist notion in favor of hashtables, or at least
encouraging one to use hashtable entries rather than plist entries.

The two parts of a symbol that *are* part of their semantics (as opposed
to part of their usage) are the symbol-name and the "identity" (read: 
address).  CL specifically makes it an error to update the symbol name;
and very little that a user can do will change the address that a symbol 
is stored in -- i.e., you are guaranteed that (eq 'foo 'foo) is always true.
[Remember why EQL was introduced into the language -- (eq n n) is *not*
guaranteed to be true for numbers, so that compilers can play the pdlnum
game].

In short, I think you have confused the structure of names [in this case,
CL symbols] with their use.


Now, on the general issue of program "constants".  PDP10 MacLisp would 
"uniquify" constants into a read-only are at load time; other lisps do 
similar things.  I believe this is the intent of the few mumbling words 
in CLtL about "constants".  More importantly, this capability of 
implementation is so important, and the hacks involved in permitting 
runtime modification of constants are so un-useful, that CL should probably
confront the issue square on.  ["un-useful", because the programmer's 
intent is never more clear when using this hack than when using a more 
approved way, such as a global parameter explicitly constructed up by 
techniques like backquote or cons etc.]

Perhaps the single most damaging piece of folklore that has confused the
issue of program constants is the PDP10 MacLisp "Pun":

    (defun quote fexpr (x) (car x))

This programmatic "Pun"  *** must not *** be allowed to serve as a 
definition for program constants.  At best, something like

    (defvar *constants-hashtable* (make-hash-table :test 'EQUAL))
    (defun quote fexpr (x) 
      (let ((form (car x)))
        (or (gethash *constants-hashtable* form)
            (setf (gethash *constants-hashtable* form)
	          (purcopy form)))))

should be thought of as minimal definition.  This is "minimal" in that at
least this much is required for the interpreter's definition of QUOTE to
match that of compiled code semantics.  And I must stress that we all 
believe this implementational style for compiled code to be necessary for
reasonable performance.  [Of course, the hashtable wouldn't really be an 
EQUAL table, as defined by CLtL, but something more akin to EQUALP.  I 
have seen the term COALESCABLEP used used.  It's probably not important
just how much "collapsing" goes on.]

A word of caution on PURCOPY:

  (1) PDP10 MacLisp treated symbols separately so that purcopy'ing one
      didn't require moving it. [incidentally, purcopy basically means
      "make me a read-only copy which is equal (or coalescablep) to
      my argument"].   I have some design notes on what to do for symbols
      when you can't do the PDP10 MacLisp hack; the issues are not semantic,
      but merely those of efficient implementaiton of SYMBOL-FUNCTION etc.

  (2) The "read only" copy needn't be be "write-protected";  of course, it
      helps if it can be made so.  Interlisp-D had a notion of unwriteable
      strings that the microcode could detect and signal an error if you
      tried to update them [well, microcode "in theory" -- maybe most
      implementations simply punted to macrocode].  The point is that "it
      is an error" to update such objects.  There are many ways to implement
      "read only" objects even if you don't want that to mean "create the
      object on a write-protected page and let the operating-system give
      the protection".  The buzz words are "Don't confuse semantics with
      implementational hacks".
      


-- JonL --