Language 'standards' for LispOS
Chris Bitmead uid
Wed, 21 May 1997 09:33:51 +1000
>Chris Bitmead uid <email@example.com> (x22068) wrote:
>> But a sub-class should be able to do everything the base class
>> can. i.e. it should conform to the same interface. So if the base
>> class has methods for mutability, then the subclass should too. What
>> you really need is a super-class.
>It seems you're assuming too much about the contract of the type CONS
>and the modification of its CAR. Let's look at the scenario from the
>point of view of inheritance as sub-contracting (as popularized by
>Bertrand Meyer, particularly in the context of Eiffel):
I've read Meyer many times, and you've got it back-to-front.
Meyer says that a sub-class may decrease the strength of preconditions
and increase the strength of postconditions. In other words, a
subclass can expect less from the caller and promise more in return,
but not the other way around.
A precondition to a method which mutates a cons cell is naturally that
the cons cell be mutable. If you subclass from cons to make
cons-immutable, then you are strengthening the pre-condition to say
that you must not pass something immutable. This is wrong!
Read Meyer, to find out why it's wrong, but basicly if you write a lot
of code designed to work with cons cells, it should work for cons and
all its subclasses. If you strengthen pre-conditions then you've just
broken all your old code, which may have been assuming that cons cells
If you do it the other way though, and make cons-immutable a super
class of cons, everything is fine.
>The language specification states that attempted mutation of certain
>data - e.g. the result of SYMBOL-NAME, or literals in source code,
>or macro arguments - has "undefined consequences". This means there's
>absolutely _nothing_ guarranteed about the consequences. It may even
>go as far as erasing your whole disk. This may appear unlikely, but
>the real-world consequences of a program modifying some conceptually
>immutable data may indeed be equally harmful - if not more so.
>Thus, a contract for e.g. (SETF (CAR X) Y) does include a precondition
>that X is not only of type CONS (note that "type" includes subclasses),
>but also that X is mutable. Unfortunately for a poor programmer, there
>just is no way to tell for sure whether an arbitrary CONS object is
>immutable or not - neither in advance nor after attempting to perform
>an invalid mutation.
>To prevent horrible damage as alluded above, some implementations
>take the option of copying such data much more often than they would
>need to; but this happens at a considerable cost - and it hides the
>error completely, which is already bad by itself. However, we can
>have the same protection, without hiding errors, and without wasting
>memory for lots of copies (which implies not only more storage, but
>also more work for the garbage collector, and possibly worse cache
>Such a CONS-IMMUTABLE subclass would simply extend the standard in
>a conforming way, by defining the consequence of contract violation
>in such cases to be that a condition is raised. This is a correct
>realization of the original contract, just more robust in the case
>of errors than what's officially required. That's a perfect subclass
>of the "fragile CONS" (which doesn't promise anything when trying
>to modify immutable data), as far as I can tell.
>-- Marc Wachowitz <firstname.lastname@example.org>