contravariant argument types: wanna?

Jeremie Pelletier jeremiep at gmail.com
Tue Sep 22 18:25:44 PDT 2009


Steven Schveighoffer wrote:
> On Tue, 22 Sep 2009 20:49:59 -0400, Jeremie Pelletier 
> <jeremiep at gmail.com> wrote:
> 
>> 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
>>
>> I can't think of an use for contravariant parameters, since a B is 
>> guaranteed to always be a A, I don't see the point of being able to 
>> declare fun(A).
>>
>> However, I would love to hear about covariant parameters, it would be 
>> most useful for interface implementations:
>>
>> interface A {
>>     A fun(A);
>> }
>> class B : A {
>>     B fun(B);
>> }
>> class C : A {
>>     C fun(C);
>> }
>>
>> Currently you need some pretty boring boilerplate code, which isn't 
>> complicated but gets repetitive when you have hundreds of such cases:
>>
>> class B : A {
>>     B fun(A) {
>>         if(B b = cast(B)b) // do stuff
>>         else throw Error("Invalid object type");
>>     }
>> }
> 
> I don't know if this is possible:
> 
> A a = new C;
> 
> a.fun(new A); // oops, you just passed an A into a function which 
> requires a C!
> 
> Are you suggesting that the compiler insert dynamic cast checks 
> everywhere?  Cause that seems like a lot of overhead...
> 
> -Steve

Not everywhere, only where it detects covariant/contravariant overrides 
or implementations. In these cases you would already use explicit 
dynamic casts so the compiler generated code would just lower the 
required boilerplate.



More information about the Digitalmars-d mailing list