[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 --