contravariant argument types: wanna?

Steven Schveighoffer schveiguy at yahoo.com
Tue Sep 22 18:19:44 PDT 2009


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



More information about the Digitalmars-d mailing list