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