DIP66 v1.1 (Multiple) alias this.

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Sun Nov 2 06:55:20 PST 2014


http://wiki.dlang.org/DIP66

I've applied some changes to it, however there are still some 
unresolved questions.

> Here's my destruction:
>
> * "symbol can be a field or a get-property (method annotated 
> with @property and taking zero parameters)." -> actually:
>
> (a) the @property annotation is not necessary
> (b) there may be one ore more parameters so long as they're all 
> defaulted
>
> So the text should be "obj.symbol must be a valid expression".

Done.

> * "At the AliasThis declaration semantic stage, the compiler 
> can perform the initial checks and reject the obviously 
> incorrect AliasThis declarations." -> it might be simpler (for 
> the sake of simplifying generic code) to just delay all error 
> checking to the first use.

I disagree with that. Current check is not recursive and prevent 
you code from a silly errors:

struct X(T, V)
{
    T t;
    V v;
    alias t this;
    alias v this; //Error if is(T == V). However this code is 
fundamentally broken, and this error should be raised as soon as 
possible.
}

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.
}

> * I don't think the pseudocode helps a lot. Better let's have a 
> clear and precise specification (I've edited the lookup order 
> into an ordered list).

Done.

> * 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.

Current (implemented is released compiler) behaviour:
import std.stdio;

struct Base
{
     string foo()
     {
         return "Base.foo";
     }
}

struct Derived
{
     Base b;
     alias b this;

     string opDispatch(string s)()
     {
         return "opDispatch";
     }
}

void main()
{
     Derived d;
     writeln(d.foo()); //prints "opDispatch"
}

After your change this call will write "Base.foo". And I see no 
way to add third "transitional" state to allow users rewrite 
those code correctly.
This changing will suddenly, without any warning, change a user 
code. I understand that this case is very rare however it may be.

And, TBH, this issue not relevant with multiple alias this :-)


> * The DIP should specify the working of alias this as 
> rewrites/lowerings, not pseudocode. Basically for each kth 
> declaration "alias symbolk this;" the compiler rewrites 
> "obj.xyz" as "obj.symbolk.xyz" and then does the usual lookup 
> on that expression. That means the whole algorithms is applied 
> again etc. If more than one rewrite typechecks, that's an 
> ambiguity error.

Ok. I've removed pseudocode. Is it better now?

> * IMPORTANT: The DIP must discuss rvalue vs. lvalue cases. The 
> rewrite approach simplifies that discussion because it's clear 
> what happens by simply reasoning about the rewritten 
> expression. Lvalue vs. rvalue matters a lot practically. 
> Consider:
>
> struct A
> {
>     private int x;
>     alias x this;
> }
>
> struct B
> {
>     private int _x;
>     int x() { return x; }
>     alias x this;
> }
>
> Then x can be passed by reference, modified directly etc. for A 
> but not for B.

Done. I've added corresponding chapter to the DIP and commit to 
the PR.


More information about the Digitalmars-d mailing list