equivariant functions

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Oct 14 19:24:52 PDT 2008


Steven Schveighoffer wrote:
> "Benji Smith" wrote
>> Steven Schveighoffer wrote:
>>> class A : IClonable
>>> {
>>>   typeof(this) clone() const { return new A();}
>>> }
>>>
>>> class B : A
>>> {
>>> }
>>>
>>> B b = new B;
>>> B x = b.clone();
>>>
>>> Oops, b.clone() really only returns A, so this should fail.  The real 
>>> signature in A should be:
>> No, b.clone() definitely returns an instance of B. It's purely 
>> coincidental (from the caller's perspective) that B's implementation is 
>> identical to that of A.
> 
> B is definitely not the same as A.  B could have a different implementation, 
> I just didn't give it one.
> 
> e.g.:
> 
> class A : IClonable
> {
>   typeof(this) clone() const { return new A(); }
>   void foo() {writefln("This is A");}
> }
> 
> class B : A
> {
>    void foo() {writefln("This is B");}
> }
> 
> B b = new B;
> b.clone().foo(); // prints "This is A"
> 
> It can't work any other way, or else the type system would be broken.

Clone is different in two ways:

1. It must be implemented in *all* derived classes

2. For each of those classes, it must return the type of that class, not 
the type of any ancestor.

Statically enforcing both 1 and 2 is the ideal case. Some languages 
allow it by allowing classes to express the actual (leaf) type of 
"this". D doesn't. I am not sure to what extent the feature is 
necessary. I would have been happy to capture it together with 
const-equivariance, but if that doesn't work, then what can I do.


Andrei



More information about the Digitalmars-d mailing list