[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

:type slot option intersections the types :-

Jim Newton

11/26/2015 4:13:00 PM

This is something surprising I learned today.

(defclass A ()
((s :type X)))

(defclass B ()
((s :type Y)))

The resulting type restriction on slot s in class b is NOT Y, but rather (AND X Y).
This means that a subclass is sadly not allowed to relax a type restriction.

This is inkeeping with the spec. indeed see 7.5.3 Inheritance of Slots and Slot Options

* The contents of a slot will always be of type (and T1 ... Tn) where T1 ....Tn are the values of the :type slot options contained in all of the slot specifiers. If no slot specifier contains the :type slot option, the contents of the slot will always be of type t. The consequences of attempting to store in a slot a value that does not satisfy the type of the slot are undefined.

5 Answers

Kaz Kylheku

11/26/2015 7:57:00 PM

0

On 2015-11-26, Jim Newton <jimka.issy@gmail.com> wrote:
> This is something surprising I learned today.
>
> (defclass A ()
> ((s :type X)))
>
> (defclass B ()
> ((s :type Y)))
>
> The resulting type restriction on slot s in class b is NOT Y, but rather (AND
> X Y).

How so? A and B are not related in any way. Maybe you wanted

(defclass B (A) ...)

> This means that a subclass is sadly not allowed to relax a type restriction.

Why would it? It violates OOP.

Above, we have defined B as *inheriting* from A.

So, by golly, that's what happened: B inherited the slot s, along
with that slot's restriction.

If B derives from A, then each instance of B *is an* A.

If what it means to be an A is to have a slot restricted to type X,
and B doesn't exhibit that restriction, then a B is not an A.
Places in the program which work with A expect the slot restriction to hold,
and if a B is substituted, it will create a surprise.

That is okay; in CLOS we don't have to derive B from A in order to
substitute instances of them in the same places. We don't even have
to derive them from the same base. They can be totally independent and just
repeat some of the common slots.

To reduce the repetition we can factor out what is common to B and A into a
common base, and just introduce the slot s differently in A and B.

> This is inkeeping with the spec. indeed see 7.5.3 Inheritance of Slots and
> Slot Options

By the way, is the substitution principle broken by the fact that we can change
the slot's :allocation in a derived class?

Suppose I make a class A in which slot s is ":allocation :class".

The Devil's Advocate argument can be made that what it means for an object to
be an A is that it shares the same value of s with all other instances.
Therefore if B is derived from A and the :allocation of s is changed to
:instance, we are breaking the principle: code which has two distinct A
objects (that are actually B) will be surprised that their s slots are not
equal.

I can't entirely reject this argument, but at the same time, overriding slot
allocation makes possible some useful and seemingly benign approaches.

Pascal J. Bourguignon

11/27/2015 4:21:00 AM

0

Kaz Kylheku <kaz@kylheku.com> writes:

> I can't entirely reject this argument, but at the same time, overriding slot
> allocation makes possible some useful and seemingly benign approaches.

You can always add a slot if you want to store an unrestricted value.

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Jim Newton

11/27/2015 10:07:00 AM

0


> >
> > (defclass A ()
> > ((s :type X)))
> >
> > (defclass B ()
> > ((s :type Y)))
> >
> > The resulting type restriction on slot s in class b is NOT Y, but rather (AND
> > X Y).
>
> How so? A and B are not related in any way. Maybe you wanted
>
> (defclass B (A) ...)
>
sorry, yes of course I meant to say B inherits from A.

(defclass A ()
((s :type X)))

(defclass B ()
((s :type Y)))


> > This means that a subclass is sadly not allowed to relax a type restriction.
>
> Why would it? It violates OOP.
>

Can't say that I agree. Yes, it is defined how it is defined, and I can accept that as a restriction. But each slot designator symbol has its own rule of inheritance, some are overridable, and some are not. For example the :initform is overridable. If A has a particular :initform and B does not, that DOES NOT mean that a B is not an A.

The restriction about :type (yes I can understand and accept) is not something I have to like.
The reason for using the :type might be for performance reasons, or it might be for behavioral reasons. If behavioral, then it is likely to be a restriction imposed by certain methods which themselves are overridable as methods on B. Unfortunately even if I override the methods on B, I cannot override the :type restriction, which is a shame in my opinion.

Jim Newton

11/27/2015 10:10:00 AM

0

On Friday, November 27, 2015 at 5:21:17 AM UTC+1, informatimago wrote:

>
> You can always add a slot if you want to store an unrestricted value.
>


Yes, that is correct, which might be indeed a good idea. If every access to the offending slot is through the accessor method, then I can provide an accessor method of the same name for the new slot in B. This could indeed work, providing all of A's methods use the accessor.

If I recall, an uninitialized (and unused) slot does not have to meet the type requirement. Right?

Thanks for the suggestion.
Jim

Marco Antoniotti

11/27/2015 10:13:00 AM

0

On Friday, November 27, 2015 at 11:07:08 AM UTC+1, Jim Newton wrote:
> > >
> > > (defclass A ()
> > > ((s :type X)))
> > >
> > > (defclass B ()
> > > ((s :type Y)))
> > >
> > > The resulting type restriction on slot s in class b is NOT Y, but rather (AND
> > > X Y).
> >
> > How so? A and B are not related in any way. Maybe you wanted
> >
> > (defclass B (A) ...)
> >
> sorry, yes of course I meant to say B inherits from A.
>
> (defclass A ()
> ((s :type X)))
>
> (defclass B ()
> ((s :type Y)))
>
>
> > > This means that a subclass is sadly not allowed to relax a type restriction.
> >
> > Why would it? It violates OOP.
> >
>
> Can't say that I agree. Yes, it is defined how it is defined, and I can accept that as a restriction. But each slot designator symbol has its own rule of inheritance, some are overridable, and some are not. For example the :initform is overridable. If A has a particular :initform and B does not, that DOES NOT mean that a B is not an A.
>
> The restriction about :type (yes I can understand and accept) is not something I have to like.
> The reason for using the :type might be for performance reasons, or it might be for behavioral reasons. If behavioral, then it is likely to be a restriction imposed by certain methods which themselves are overridable as methods on B. Unfortunately even if I override the methods on B, I cannot override the :type restriction, which is a shame in my opinion.

I remembered about "contravariace" by reading this thread. Wikipedia has the following page on the subject (where I learned that C# does something interesting with it).

https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_...

Cheers
--
MA