DIP66 v1.1 (Multiple) alias this.

Sativa via Digitalmars-d digitalmars-d at puremagic.com
Sun Nov 2 11:57:29 PST 2014


> class A : B
> {
>    B b;
>    alias b this; //Error: super type (B) always hides 
> "aliasthised" type B because base classes should be processed 
> before alias this types.
> }
>

This isn't an error? Just because A inherits B doesn't mean that 
the alias is wrong?

e.g., If you have

class A1 { B b; alias b this; }

and

class A2 : B { B b; alias b this; }

A2 is just A1 in all forms. Whats great about it is that it 
allows easy composition patterns. (that is, A1 has essentially 
implemented B through the alias)

e.g., we can reassign b to a different behavior without having to 
write any boil code. It allows one to decompose classes and their 
implementations in a natural way.

Of course, it would require the alias this to be processed before 
the base class.

I think that it would be worth the alias to override the 
inheritance because it makes things easier:


class A : BBB { BB b; alias b this; }

If BBB and BB are related in some complex way the compiler has to 
deduce this. e.g.,

class BBB : Q!B { }

where Q!B is some template that is a superclass of B.

But if the alias is processed first, it won't matter.


>> * Regarding the lookup, opDispatch shouldn't come before alias 
>> this, or should come before base class lookup. Essentially 
>> alias this is subtyping so it should enjoy similar privileges 
>> to base classes. A different way to look at it is opDispatch 
>> is a "last resort" lookup mechanism, just one step above the 
>> UFCS lowering.
>
> I agree with this suggestion, however it breaks an existing 
> code.
> opDispatch shouldn't come before base type lookup, because it 
> will hide basic methods like toString.
> opDispatch may come after alias this lookup, however it will 
> fundamentally change program behaviour.

Why can't you simply have opDispatch call the base class lookup 
if all others fail?

It seems to me that one should have

alias this > opDispatch > class > base class(es)

But each one has a fall through mechanism.

e.g., if someone overrides toString in opDispatch it will call 
their function, if not, it gets passed to the bass class tostring.

Why should it work this way? Because alias this and opDispatch 
are user defined. The user "knows" why they are doing and the 
compiler doesn't get in the way by preventing them from doing 
things they want to do.

The compiler essentially fixes up all the missing connections 
that it can but never forcing connections the user may not want.


Basically all one needs is something like

bool opAliasDispatch(...)
{
    if (...) { ... return true; } // tries to dispatch
    return false;
}


bool opDispatch(...)
{
    if (...) { ... return true; } // tries to dispatch
    return false;
}

bool opClassDispatch(...)
{
    if (...) { ... return true; } // tries to dispatch
    return false;
}

bool opBaseDispatch(...)
{
    if (...) { ... return true; } // tries to dispatch
    return false;
}

Then a master dispatcher is

bool opMasterDispatch(...)
{
    return opAliasDispatch(...) || opDispatch(...) || 
opClassDispatch(...) || opBaseDispatch(...);
}



This makes it easier to add new dispatchers in the future, etc.

Also, if you are worried about backwards compatibility, just 
create a command line switch to select one method over another. 
Easy and it doesn't force everyone to be stuck with a suboptimal 
solution just for "backwards compatibility"(which is the scourge 
of humanity... We have to move forward, not be stuck in the 
past!!!).



More information about the Digitalmars-d mailing list