The year is 2019

Mike Franklin slavo5150 at yahoo.com
Sat Jul 27 09:04:45 UTC 2019


On Saturday, 27 July 2019 at 05:09:18 UTC, Manu wrote:

> The obvious counterpart to `@implicit` constructors is probably
> `@implicit` cast operators.
> Those aren't quite the same as "alias this stuff into 'this' 
> scope",
> and at that very specific semantic, I think `alias this` is
> occasionally useful, but if you're just trying to emulate 
> implicit
> construction or implicit casting, then I think there are better 
> and
> more deliberate ways to do that, possibly with `@implicit`.

I would be perfectly happy with `opImiplicitCast` or some way to 
have implicit constructors.  But Walter has already voiced his 
disapproval of that (See the comments in 
https://github.com/dlang/dmd/pull/10161 for the disappointment), 
so our choices are getting slim.  I'm trying to find something he 
would be willing to approve. If you have any ideas, I'm all ears.

I'm currently trying to collect ideas from others.  Alex 
(12345swordy) gave me some good ideas yesterday, and I'm 
internalizing them.

Here's what I'm thinking right now:

Walter opposes implicit casts, but we already have `alias this`.  
`alias this` currently does 2 things: (1) It simulates an 
implicit cast (2) It forwards unresolved symbols to the aliased 
member.  The problem with `alias this` is (2), and that causes a 
lot of resolution bugs and other "weird sh**". (1) is fine.

(1) is all we need because we have enough metaprogramming 
facilities to implement (2) in the library.  What I'm thinking is 
that we create a more limited `alias this` that only does (1).  
I'm thinking about syntax like this to distinguish it from the 
existing `alias this` feature.

struct Base
{
     void method1() { }
     void method2() { }
}

struct Derived
{
     Base b;
     alias b;  // `this` is implicit.  That will distinguish it 
from
               // `alias b this` as the more limited `alias this` I
               // proposed above.  It is an error to use both 
forms.

     mixin ForwardPublicMembers!(b);
     // The above mixin is a utility in the library that generates 
the
     // following
     //
     // void method2()
     // {
     //     b.method2();
     // }
     //
     // void method2()
     // {
     //     b.method2();
     // }
}

void foo(Base b) { }

void main()
{
    Derived d;
    foo(d);    // Works because (1) -- the implicit casting 
behavior of
               // `alias this` is retained with `alias b`
}

This will keep the current `alias this` working as is, but allow 
us to introduce a new form.  Why I think I might be able to make 
the case to Walter...

1.  It's not the wild west of `opImplicitCast` or implicit 
constructors, which Walter already says he won't approve.
2.  It's not much different from what we have today with `alias 
this`, so it's not a radical change, which I think Walter will 
appreciate.
3.  If users migrate away from `alias b this;` and prefer `alias 
b;` then we may be able to deprecate the `alias b this` form 
along with all of its "weird sh**" resolution problems and bugs.  
I think Walter will appreciate that also.
4.  In the long term, if `alias this` is deprecated we will be 
able to delete a huge mess of complexity from the compiler, and I 
think that will be appealing to Walter as well.
5.  It doesn't break any existing code.  `alias b this` will 
still work until we decide we don't want to support it anymore.  
This is an "addition-only" change.

I may be wrong with my speculation here, but given the 
constraints Walter has voiced, it's the best I can think of.  
Either that or we have to try to convince Walter to embrace 
implicit casting, and you all know how that will likely end up.  
The only other saving grace may be Atila.

Mike


More information about the Digitalmars-d mailing list