contravariant argument types: wanna?
Jeremie Pelletier
jeremiep at gmail.com
Wed Sep 23 08:39:42 PDT 2009
Andrei Alexandrescu wrote:
> Jeremie Pelletier wrote:
>> Yigal Chripun wrote:
>>> On 23/09/2009 03:07, Andrei Alexandrescu wrote:
>>>> Hello,
>>>>
>>>>
>>>> Today, overriding functions have covariant return types:
>>>>
>>>> class A {
>>>> A clone();
>>>> }
>>>>
>>>> class B : A {
>>>> B clone(); // fine, overrides A.clone
>>>> }
>>>>
>>>> That is entirely principled and cool. Now the entire story is that
>>>> overriding function may have not only covariant return types, but also
>>>> contravariant argument types:
>>>>
>>>> class A {
>>>> A fun(B);
>>>> }
>>>>
>>>> class B : A {
>>>> B fun(A); // fine (in theory), overrides A.fun
>>>> }
>>>>
>>>> Today D does not support contravariant arguments, but Walter told me
>>>> once he'd be quite willing to implement them. It is definitely the
>>>> right
>>>> thing to do, but Walter would want to see a compelling example before
>>>> getting to work.
>>>>
>>>> Is there interest in contravariant argument types? If so, do you
>>>> know of
>>>> a killer example?
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> Andrei
>>>
>>> consider:
>>>
>>> class Car { ... }
>>> class Truck : Car { ... }
>>>
>>> class Driver {
>>> void drive (Car c);
>>> }
>>>
>>> class truckDriver : Driver {
>>> void drive(Truck t); // NOT contra-variant !!
>>> }
>>>
>>> does the above design will be affected by your suggestion?
>>
>> You just described covariant arguments, which is a feature i'd also
>> like to see. It's different from contravariant arguments, implementing
>> one does not give the other unfortunately.
>
> Well there's a good reason for it: contravariant arguments are sound,
> covariant arguments aren't. My belief is that a design that would need a
> lot of argument covariance ought to be analyzed.
Have you read my other post in this thread where I show an actual
example of covariant arguments from my display interface, my I/O
interfaces also use covariant arguments although they're more friendly
to generic interface parameters.
The point is, you see covariance all the time in interface programming
when implementations expect an interface argument to be an object from
that same implementation. As soon as you use an abstract factory to let
the world use some implementation without being aware of which one it
is, you're bound to see covariance at some point. Most people just code
it explicitly, the mozilla code is *full* of explicit covariant
interface requests.
While they may not be sound, its still a scenario you're gonna come
across sooner or later, and a scenario which involves lots of similar
boilerplate that can easily be generated by the compiler.
Jeremie
More information about the Digitalmars-d
mailing list