> What Meyers shows is a hierarchy with a class Skier with
> two subclasses, Girl and Boy.
haha. as an aside, i'm not a big fan of these types of scenarios as (1) they misuse inheritance, and (2) date very quickly. it kind of reminds me of the model in the sina composition filters paper that models Secretary as a subclass of Spouse (which is assumed to be female). Employees who have secretaries are assumed to be male of course!!
http://trese.cs.utwente.nl/oldhtml/publications/reports/cf.pdf> In Eiffel I think the subclass share methods override
> (actually implement, since it is abstract) the share
> method in Skier, because this kind of covariance of
yes, i believe these these override in eiffel. i can't even remember if eiffel has overloading.
> Meyers then later says, in a section entitled "polymorphic
> perversity", that "a harmful scheme is easy to make up,"
> and gives this example (again translated to Java):
yes, it's easy to make up a scenario where parameter covariance leads to runtime holes. whether it is a major problem in practice is another question.
> contravariance is of essentially no practical use.
I'd agree with bertrand here. I've found contravariance of input parameters to be useless. covariance is statically unsound, and therefore the java position of invariance seems sensible in a record type model. (Obviously contravariance of return types is a different story)
> In computing science as in other disciplines, it is after
> all much easier to device drastically simple theories if
> we neglect to make them agree with reality.
we just spend so much time trying to form the perfect type system that I wonder if it would be better to accept occasional holes for simplicity and clarity. It's the old 80/20 rule. To me Bertrand's crazy example sort of makes sense. You have a boy skier and a girl skier and they can't share a room. However, if you just tell someone you have 2 skiers and to put them in a room together, and you do it, someone's going to get in trouble ;-)
> So he suggests that the "rare but serious
> possibility of type violations when [covariance is]
> combined with polymorphism," as he put it, are something
> that can be managed and are worth getting the benefit of
> being able to model this kind of reality. He never said it
> was about covariance being simpler or easier to
> understand, just that he want to be able to model things
> like making sure Girl and Boy skiers stay in separate
> rooms.
fair enough. i find it simpler then to understand from a modeling perspective. for instance, if you have a Java class animal:
class Animal { void eat(Food f) {}}
and you want to subclass it to make Bear, you'd ideally want:
class Bear extends Animal { void eat (Honey h) {} }
where eat is overridden and Honey is a subclass of Food. To me this makes modeling sense, even though we can then ask the question as to what happens if we feed a bear weetabix...
> So fast forward 12 years, and here's how you could do this
> in Scala that keeps both the types and the high schoolers
> out of trouble. First, in Skier you add an abstract type
> as a member:
>
>
> abstract class Skier {
> type SuitableRoommate <: Skier
> def share(other: SuitableRoommate)
> }
>
>
> The <: means that type SuitableRoommate must be a subtype
> of Skier. The SuitableRoommate type is abstract, because
> there's no equals sign specifying it to be some other
> type. The share method is also abstract, as in the Java
> example I showed previously, because it has no definition.
> In Scala, you don't need to put the keyword abstract on
> these as in Java.
yes, you do it the same sort of way in Beta with virtual patterns. In Beta you still have type holes because the Boy and Girl would still be subclasses of Skier.
So, in your scala example, does it mean that Boy and Girl are no longer subclasses of skier? if they are, what happens if you call Skier::share() on a boy as a Skier and pass in a girl as a Skier?
So, the idea of putting the share() function in the base class must be so that Boy and Girl can be treated polymorphically from the perspective of the share() method at some point, surely? otherwise, why wouldn't you just omit it from the Skier base and just place share(Girl) on the Girl class and vice versa?
And if Boy and Girl are no longer substitutable for Skier, then haven't we lost something major?
Alternatively, i'm not understanding how Scala handles this.
Cheers,
Andrew