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

constant smashing



>From:	IN%"NGALL@G.BBN.COM" 17-JUN-1988 07:02
>Subj:	Re: Constant Smashing
>
>    From: ELIOT@cs.umass.edu
>    
>    ...
>    Further supporting the idea that a general mechanism apart from QUOTE
>    is required to properly support read-only data structures, if read
>    only data becomes a Common Lisp concept.
>    
>Agreed.
>

...
>    >	(defun foo ()
>    >	    '(a b c))
>    >	
>    >	Really means
>    >	
>    >	(defun foo ()
>    >	    G00047)
>    >	(setq G00047 '(a b c))
>    >

>What IS mutable (which neither def. suggests strongly enough) is
>the list itself.  Again this suggests a different notation for RO is
>needed.

THAT is my point.  In particular def. 1 does not suggest it strongly
enough for it to be a reasonable interpretation.  In fact, def. 1
strongly suggests that it will always return (A B C). The source
code makes this reading so natural that I think it must be chosen
as the defined semantics, regardless of the context that FOO
is executed in.  It is completely unnatural to allow some other
function to reach out of nowhere and dig around in the guts of
FOO resulting in changes to its behavior.

Intentionally modifying a quoted constant does not provide any
functionality that cannot be achieved using a global variable.
The global variable can be encapsulated in a lexical closure
to make its use even clearer.  This easilly produces the same
effects and the code will more closely approximate its true
intention.

>>    
>>    >It is also the
>>    >semantics of all (?) CL interpreters.  QUOTE MUST have the same
>>    >behavior in the compiler and the interpreter.  To do otherwise is to
>>    >introduce a compiler/interpreter incompatibility as confusing and
>>    >error-prone as the SPECIAL variable incompatibility used to be.  Agreed?
>>    
>>No.  QUOTE must have the same *semantics* in the compiler and
>>interpreter.

>I was unclear.  I meant that the compiler and
>interpreter must BEHAVE identically.  My point is a pedagogical one:
>people learn lisp in the interpreter.  Textbooks use (and motivate)
>QUOTE as if ALL that it does it to prevent evaluation and interpreters
>support this model.  I feel would not be sufficient for CLtL to merely
>state that "it is an error" to modify the arg of QUOTE and enforce in
>in the compiler but not the interpreter.  This is what leads to the
>continual confusion of neophytes.

(1) If Common Lisp does not specify the behavior in some case an
implementation is free to do anything at all.  It could be said that
Common Lisp will "Signal an error if any attempt is made to modify
a quoted constant" and then the compiler/interpreter would have
to behave identically.  Since this is not practical for all implementations
the phase "It is an error" must be used instead.

(2) Textbooks can only be granted limited authority over *proposed*
changes.  If Common Lisp changes or gets clarified then the textbooks
will have to be updated.  Otherwise the situation is a little like
having the tail wag the dog.

(3) You can't learn *any* portable language by experimenting with it
if any part of the specification is incomplete.  Experimentation
shows the behavior of the *implementation* but cannot distinguish
between the core language and its extensions.  Before Common Lisp
the implementation was the specification, so this was not a problem.
In the future textbooks and teaching material must emphasize the 
difference, and provide cautions about assuming trusting experimentally
revealed behavior.  If it is not DOCUMENTED then you can't trust it.

>
>    In the case of QUOTE some errors might go undetected.  This is not good,
>    but it is not as dangerous a flaw as the SPECIAL variable problem,
>    which is characterized by different compiled/interpreted behavior
>    where neither behavior draws attention to the actual source of the
>    problem.  It is relatively straightforward to debug a problem that
>    causes the debugger to freeze execution near the actual cause.
>
>Three: 1) What if the the RO-ness of the object was the bug.
>Finding the source of the object could be very difficult.

One measure of bug "complexity" is how much of the actual
cause of the bug (code or data) will be "obvious" when the
bug occurs.  Wrong numbers might have come from anywhere,
so they can be very hard to debug.  RO-ness will at least
cause the debugger to point at the data structure that
is involved, but probably not the code.  Thus, at worst,
it would be classified as a medium difficult bug.

>2) I have
>heard from at least 2 lisp implementors (on stock harware) that they
>will not enforce the RO-ness of a QUOTEd object until system build
>time, not compile time!  It takes us over an hour to build our system.
>What a debug cycle! :-)

Patching avoids the need to go all the way around the debug
cycle.

>[Actually this brings up the general issue of
>a third kind of "code": interpreted, compiled, and "built".] 3) Its
>not the debugging difficulty alone that bothers me, it is mere
>difference in behavior between the compiler and interpreter in a very
>common case.

To rationally decide if a difference is "reasonable" requires something
like a cost/benefit analysis.  The benefit is measured in terms of
efficieciency and simplicify of the implementation.  What measures
the cost?  It must be a combination of the likelihood that a bug
will come of it, and the difficulty of finding the bug.  So I claim
that you *should* be primarilly concerned with the difficulty
of finding the bug that *should* determine if the mere difference
alone is bothersome.

>    
>    To support this argument I must make one more claim.  I must claim that
>    compiling a function produces a *new* function definition that is
>    semantically equivalent to the old one, but it does not have to
>    be composed of the 'same' forms.
>Agreed.
>    This is because of the definition of
>    CONSTANTP on p.324 (CLtL) which (in my reading) implies (eq (foo) (foo))
>    when FOO is defined as above.  [Because of (constantp (quote a b c))]
>
>Disagree. CONSTANTP uses the vague expression "evaluate to the same
>thing".  Which version of SAME is it talking about? EQ EQL or EQUAL
>Can't be EQ since CONSTANTP is true of numbers.  I claim SAME means
>EQUAL, because of CLtLs EQUAL constant collapsing which IN THEORY
>allows QUOTE to cons an EQUAL copy of its argument each time the QUOTE
>form is evaluated. (As my pseudo-definition of QUOTE stated in a
>previous message.)

I assumed that SAME meant EQL.  Obviously that should be clarified.
I never heard of CONSTANTP before, so I speak from experience: none of it.

>    Therefore:
[1] >	    (eq (foo) (foo)) => T
>	    (setq x (foo))
>	    (compile 'foo)
[2] >	    (eq x (foo)) => Ambiguous
[3] >	    (eq (foo) (foo)) => T
>
>No. (eq (foo) (foo)) => Ambiguous. This is why I want to flush EQUAL
>constant collapse from CLtL.  I want it to be T.

I agree that [1] & [3]  *should* be T, especially if EQL is substituted for EQ.
I don't care about EQUAL constant collapse, but it seems harmless
if you accept RO.

>    
>    And no identity holds accross the act of compilation.

Chris Eliot