Multiple subtyping with alias this and nested classes

Max Samukha spambox at d-coding.com
Mon Oct 5 03:19:07 PDT 2009


On Sun, 04 Oct 2009 12:31:08 -0400, Yigal Chripun <yigal100 at gmail.com>
wrote:

>Max Samukha Wrote:
>> >
>> >I see. What you want is non-virtual MI. 
>> >I don't think that allowing the derived class to have two distinct implementations for the same function prototype is a good idea. 
>> >Eiffel handles this by giving the programmer controls to select features and rename them in the derived class which I think is better. 
>> >
>> >// hypothetical syntax example
>> >class FlippingBlipper : IBlipper, IFilpper {
>> >     mixin Flipper F;
>> >     mixin Blipper B;
>> >     // rename the inherited interface functions 
>> >     alias IBlipper.nameCollision boo;
>> >     alias IFilpper.nameCollision foo;
>> >    // implement the now two distinct functions
>> >   void foo() { F.nameCollision(); }
>> >   void boo() { B.nameCollision(); }
>> >}
>> >
>> >you can further subtype and the derived foo & boo will override the respective interfaces. 
>> 
>> Yes, but what if nameCollision is a virtual function called somewhere
>> in the template mixin? Your example has effectively removed the
>> virtuality.
>> 
>
>it doesn't remove virtuality. Virtual functions are stored as pointers in the vtable. with my suggested solution the idea is that the same pointer in the vtable gets a new name in the derived class. 
>when you mixin the template into the derived class the compiler would  resolve nameCollision to the new name "foo" because of the renaming rule in the derived class. 

Ok, I still cannot see how the compiler can reliably determine that
IFlipper.nameCollision is implemented by Flipper and not by Blipper
and call the correct override when flip is called.

Should the compiler deduce that from F.nameCollision? If yes, what
about:
void foo() { B.nameCollision; F.nameCollision; } ?

Or should it decide based on the fact that Flipper contains the 'flip'
function that implements IFlipper.flip? If yes, then what if the
interfaces had nothing more than the 'nameCollision' functions?

>I don't think I want non virtual MI in D since it is more trouble than it's worth. but *if* we discuss this, I think my suggested semantics are simpler. The syntax probably can be much better but that's a secondary issue IMO.
>

It's unrelated to virtual MI. See Sergey Gromov's post. We are
discussing this only because it's a real world problem that has no
decent solution in D.

>
>with my design: 
>class Foo : FlippingBlipper {
> override foo ...
> override bar ...
>} 
>IFlipper obj = new Foo; 
>obj.nameCollision; // will call Foo.bar

>
>I don't think that's possible with your design.

I'm not claiming it's my design. Andrei is the author.

And yes, it's possible in a number of ways. One is:

class BlippingFlipper
{
   class Flipper_ : Flipper
   {
     override void nameCollision()  {  foo(); }
     final void super_nameCollision() { super.nameCollision;  }
   }

   this() { flipper = new Flipper_; }

   Flipper_ flipper;
   alias flipper this;

   void foo() { flipper.super_nameCollision; }
}

class Foo : BlippingFlipper
{
    override void foo() {}
}

(Wordy but still possible. Can be made easier on the eye with a helper
mixin)

I agree that possibility to implement renamed interface methods AND
explicit interface implementation would solve the problem of name
collisions. But it doesn't solve the problem of subtyping structs and
built-in types.

>
>besides, alias this is a hack. a better mechanism would be to have compile-time inheritance, IMO.

I think 'alias this' is a powerful feature.

Given the constraints like "easy for the compiler writer to implement"
and "we have many other things to do", I doubt traits or something
like that will be or needs to be in the language.



More information about the Digitalmars-d mailing list