Jump to page: 1 26  
Page
Thread overview
Multiple alias this, what's the hold up?
Jun 15, 2019
Amex
Jun 15, 2019
12345swordy
Jun 16, 2019
Jonathan Marler
Jun 16, 2019
Timon Gehr
Jun 16, 2019
Walter Bright
Jun 16, 2019
Jonathan Marler
Jun 16, 2019
Mike Franklin
Jun 16, 2019
Walter Bright
Jun 16, 2019
Mike Franklin
Jun 16, 2019
Timon Gehr
Jun 16, 2019
Walter Bright
Jun 16, 2019
Adam D. Ruppe
Jun 16, 2019
Timon Gehr
Jun 16, 2019
Timon Gehr
Jun 17, 2019
Walter Bright
Jun 17, 2019
Timon Gehr
Jun 18, 2019
Exil
Jun 18, 2019
user1234
Jun 19, 2019
Exil
Jun 16, 2019
Amex
Jun 17, 2019
Guillaume Piolat
Jun 17, 2019
Ethan
Jun 18, 2019
Olivier FAURE
Jun 18, 2019
Ali Çehreli
Jun 18, 2019
Jonathan M Davis
Jun 19, 2019
Mike Franklin
Jun 19, 2019
Jonathan M Davis
Jun 19, 2019
Jonathan Marler
Jun 19, 2019
aliak
Jun 19, 2019
Les De Ridder
Jun 19, 2019
Jonathan M Davis
Jun 16, 2019
Jonathan Marler
Jun 16, 2019
Timon Gehr
Jun 16, 2019
Jonathan Marler
Jun 16, 2019
aliak
Jun 16, 2019
Mike Franklin
Jun 17, 2019
Adam D. Ruppe
Jun 17, 2019
Mike Franklin
Jun 17, 2019
Jonathan Marler
Jun 17, 2019
user1234
Jun 17, 2019
rikki cattermole
Jun 17, 2019
user1234
Jun 17, 2019
rikki cattermole
Jun 17, 2019
user1234
Jun 18, 2019
Mike Franklin
Jul 11, 2019
Basile B.
Jun 17, 2019
Timon Gehr
Jun 17, 2019
12345swordy
Jun 17, 2019
user1234
Jun 18, 2019
Mike Franklin
Jun 18, 2019
Timon Gehr
June 15, 2019
How many years has it been in limbo? 1? 2? 3? 5? 10?

What is the hold up?


Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false)
{
    for (AggregateDeclaration ad = isAggregate(e.type); ad;)
    {
        if (ad.aliasthis)
        {
            uint olderrors = gag ? global.startGagging() : 0;
            Loc loc = e.loc;
            Type tthis = (e.op == TOK.type ? e.type : null);
            e = new DotIdExp(loc, e, ad.aliasthis.ident);
            e = e.expressionSemantic(sc);
            if (tthis && ad.aliasthis.needThis())
            {
                if (e.op == TOK.variable)
                {
                    if (auto fd = (cast(VarExp)e).var.isFuncDeclaration())
                    {
                        // https://issues.dlang.org/show_bug.cgi?id=13009
                        // Support better match for the overloaded alias this.
                        bool hasOverloads;
                        if (auto f = fd.overloadModMatch(loc, tthis, hasOverloads))
                        {
                            if (!hasOverloads)
                                fd = f;     // use exact match
                            e = new VarExp(loc, fd, hasOverloads);
                            e.type = f.type;
                            e = new CallExp(loc, e);
                            goto L1;
                        }
                    }
                }
                /* non-@property function is not called inside typeof(),
                 * so resolve it ahead.
                 */
                {
                    int save = sc.intypeof;
                    sc.intypeof = 1; // bypass "need this" error check
                    e = resolveProperties(sc, e);
                    sc.intypeof = save;
                }
            L1:
                e = new TypeExp(loc, new TypeTypeof(loc, e));
                e = e.expressionSemantic(sc);
            }
            e = resolveProperties(sc, e);
            if (gag && global.endGagging(olderrors))
                e = null;
        }

        import dmd.dclass : ClassDeclaration;
        auto cd = ad.isClassDeclaration();
        if ((!e || !ad.aliasthis) && cd && cd.baseClass && cd.baseClass != ClassDeclaration.object)
        {
            ad = cd.baseClass;
            continue;
        }
        break;
    }
    return e;
}

June 15, 2019
On Saturday, 15 June 2019 at 10:12:46 UTC, Amex wrote:
> How many years has it been in limbo? 1? 2? 3? 5? 10?
>
> What is the hold up?

What the hold up is that walter thinks it is a bad idea to implement multiple alias this as he think it results in a multiple inheritance problem. There has been recent discussion regarding deprecating alias this.
June 16, 2019
On Saturday, 15 June 2019 at 23:30:09 UTC, 12345swordy wrote:
> On Saturday, 15 June 2019 at 10:12:46 UTC, Amex wrote:
>> How many years has it been in limbo? 1? 2? 3? 5? 10?
>>
>> What is the hold up?
>
> What the hold up is that walter thinks it is a bad idea to implement multiple alias this as he think it results in a multiple inheritance problem. There has been recent discussion regarding deprecating alias this.

Maybe we could add it as an optional feature enabled with a command-line option?

I think there's a command line format for features like this "-feature=miltialias" or something.

That way if there really are issues we could demonstrate them and remove the feature later, or if no issues are found it could be enabled by default.
June 16, 2019
On 16.06.19 03:04, Jonathan Marler wrote:
> On Saturday, 15 June 2019 at 23:30:09 UTC, 12345swordy wrote:
>> On Saturday, 15 June 2019 at 10:12:46 UTC, Amex wrote:
>>> How many years has it been in limbo? 1? 2? 3? 5? 10?
>>>
>>> What is the hold up?
>>
>> What the hold up is that walter thinks it is a bad idea to implement multiple alias this as he think it results in a multiple inheritance problem. There has been recent discussion regarding deprecating alias this.
> 
> Maybe we could add it as an optional feature enabled with a command-line option?
> 
> I think there's a command line format for features like this "-feature=miltialias" or something.
> ...

That probably won't fly.

> That way if there really are issues we could demonstrate them and remove the feature later, or if no issues are found it could be enabled by default.

In terms of lookup, the issues with multiple alias this are the same as the issues with multiple import declarations. Implicit conversions could use the same lookup rules, but there would need to be a way to disambiguate. The code in the compiler that implements import declarations is unlikely to be easily reusable.
June 15, 2019
On 6/15/2019 6:21 PM, Timon Gehr wrote:
> In terms of lookup, the issues with multiple alias this are the same as the issues with multiple import declarations. Implicit conversions could use the same lookup rules, but there would need to be a way to disambiguate. The code in the compiler that implements import declarations is unlikely to be easily reusable.

Multiple alias this is multiple inheritance. Generally, if you find yourself wanting multiple inheritance, it's likely time to rethink the data structures.
June 16, 2019
On Sunday, 16 June 2019 at 01:21:16 UTC, Timon Gehr wrote:
> On 16.06.19 03:04, Jonathan Marler wrote:
>> On Saturday, 15 June 2019 at 23:30:09 UTC, 12345swordy wrote:
>>> On Saturday, 15 June 2019 at 10:12:46 UTC, Amex wrote:
>>>> How many years has it been in limbo? 1? 2? 3? 5? 10?
>>>>
>>>> What is the hold up?
>>>
>>> What the hold up is that walter thinks it is a bad idea to implement multiple alias this as he think it results in a multiple inheritance problem. There has been recent discussion regarding deprecating alias this.
>> 
>> Maybe we could add it as an optional feature enabled with a command-line option?
>> 
>> I think there's a command line format for features like this "-feature=miltialias" or something.
>> ...
>
> That probably won't fly.
>
>> That way if there really are issues we could demonstrate them and remove the feature later, or if no issues are found it could be enabled by default.
>
> In terms of lookup, the issues with multiple alias this are the same as the issues with multiple import declarations. Implicit conversions could use the same lookup rules, but there would need to be a way to disambiguate. The code in the compiler that implements import declarations is unlikely to be easily reusable.

Having a hard time trying to figure out what you mean here.  I'm not sure what you mean by "multiple import declarations".  Is this what you mean?

import std.stdio;
import std.stdio;

Or maybe this?

import std.stdio;
void foo()
{
    import std.stdio;
}

Then you said "Implicit conversions could use the same lookup rules", but I'm not sure what you're saying there either.  Maybe if I understood what you meant my "import declarations" then it would make sense?

Sorry if I just missed something.

June 16, 2019
On Sunday, 16 June 2019 at 06:08:54 UTC, Walter Bright wrote:
> On 6/15/2019 6:21 PM, Timon Gehr wrote:
>> In terms of lookup, the issues with multiple alias this are the same as the issues with multiple import declarations. Implicit conversions could use the same lookup rules, but there would need to be a way to disambiguate. The code in the compiler that implements import declarations is unlikely to be easily reusable.
>
> Multiple alias this is multiple inheritance. Generally, if you find yourself wanting multiple inheritance, it's likely time to rethink the data structures.

There's not many cases where I've really needed/wanted multiple alias this.  I do have one case where I thought it would be nice which I'll share for anyone interested.

It was when I created the SentinelArray/SentinelPtr types.  They represent arrays and pointers that are ended with a sentinel value.

https://github.com/dragon-lang/mar/blob/master/src/mar/sentinel.d

For example, a cstring would be a SentinelPtr!char. The reason for creating these types is to allow the type system to know whether or not a pointer already has a sentinel value. This is most useful when interfacing with C functions that take C strings. Declaring the string pointer as a SentinelPtr allows the type-system to both verify that all strings are null-terminated and allows the application to control when conversions from D-Strings to C-Strings occur rather than performing a conversion every time the function is called.

To make these Sentinel types play well with the type system, I also supported using type modifiers like 'const' and 'immutable':

SentinelPtr!char
SentinelPtr!(const char)
SentinelPtr!(immutable char)

The reason for "alias this" would be to have them be implicitly convertible to both raw pointers for the mutable/immutable variants to be implicitly convertible to the const variant.  So you could do things like:

//
// Implicitly convertible to raw pointer
//
void takesRawPointer(char* ptr);

SentinelPtr!char p = ...;
takesRawPointer(p);

//
// Mutable/Immutable implicitly convertible to const
//
void takeConstSentinelPtr(SentinelPtr!(const char) filename);

SentinelPtr!char filename1 = ...;
takeConstSentinelPtr(filename1);
SentinelPtr!(immutable char) filename2 = ...;
takeConstSentinelPtr(filename2);

Since multiple alias this only supports one member I couldn't have both.  So I chose to use alias this to convert mutable/immutable to const and raw pointer conversions requires an explicit member access (i.e. `mySentinelPtr.raw`).  Having to call a member is not horrible, but having multiple alias this seems like it would be nicer.

Anyway, thought it might be helpful to see a real use case.

Of course, if anyone knows of a better solution to this problem I'm all ears :)
June 16, 2019
On Saturday, 15 June 2019 at 10:12:46 UTC, Amex wrote:
> How many years has it been in limbo? 1? 2? 3? 5? 10?
>
> What is the hold up?
>

DIP66 is in need of champion.  Do you wish to adopt https://github.com/dlang/dmd/pull/8378 and see it across the finish line?

But I'm curious.  Is there anything that `alias this` can do that can't be replicated with a mataprogramming library?

Contrived, naive, very incomplete illustration:

```
import std.stdio;
import std.traits;

template AliasThis(alias f)
{
    static foreach(m; __traits(allMembers, typeof(f)))
    {
        mixin(
            ReturnType!(__traits(getMember, typeof(f), m)).stringof
            ~ " " ~ m ~ "()"
            ~ "{" ~ __traits(identifier, f) ~ "." ~ m ~ "(); }"
        );
    }
}

struct Base
{
    void print()
    {
        writeln("Base.print");
    }

    void print2()
    {
        writeln("Base.print2");
    }
}

struct Base2
{
    void print3()
    {
        writeln("Base2.print3");
    }

    void print4()
    {
        writeln("Base2.print4");
    }
}



struct Derived
{
    Base base;
    Base2 base2;
    mixin AliasThis!(base);
    mixin AliasThis!(base2);
}

void main()
{
    Derived d;
    d.print();
    d.print2();
    d.print3();
    d.print4();
}
```

Mike
June 16, 2019
On Sunday, 16 June 2019 at 06:08:54 UTC, Walter Bright wrote:

> Multiple alias this is multiple inheritance. Generally, if you find yourself wanting multiple inheritance, it's likely time to rethink the data structures.

If one should prefer composition to inheritance the language must provide the proper facilities to make composition just as convenient.

I refer you to this StackOverflow question (https://stackoverflow.com/questions/255553/is-it-possible-to-implement-mixins-in-c) where a C# user was looking for a convenient way to reuse and aggregate implementations.  The second comment to the question says it all:

> I find it annoying that C++ experts make statements like "Prefer composition to inheritance" yet the language (C++ or C#) offers precious little help to do the "right thing".

Mike
June 16, 2019
On 16.06.19 08:19, Jonathan Marler wrote:
> On Sunday, 16 June 2019 at 01:21:16 UTC, Timon Gehr wrote:
>> On 16.06.19 03:04, Jonathan Marler wrote:
>>> On Saturday, 15 June 2019 at 23:30:09 UTC, 12345swordy wrote:
>>>> On Saturday, 15 June 2019 at 10:12:46 UTC, Amex wrote:
>>>>> How many years has it been in limbo? 1? 2? 3? 5? 10?
>>>>>
>>>>> What is the hold up?
>>>>
>>>> What the hold up is that walter thinks it is a bad idea to implement multiple alias this as he think it results in a multiple inheritance problem. There has been recent discussion regarding deprecating alias this.
>>>
>>> Maybe we could add it as an optional feature enabled with a command-line option?
>>>
>>> I think there's a command line format for features like this "-feature=miltialias" or something.
>>> ...
>>
>> That probably won't fly.
>>
>>> That way if there really are issues we could demonstrate them and remove the feature later, or if no issues are found it could be enabled by default.
>>
>> In terms of lookup, the issues with multiple alias this are the same as the issues with multiple import declarations. Implicit conversions could use the same lookup rules, but there would need to be a way to disambiguate. The code in the compiler that implements import declarations is unlikely to be easily reusable.
> 
> Having a hard time trying to figure out what you mean here.  I'm not sure what you mean by "multiple import declarations".  Is this what you mean?
> 
> import std.stdio;
> import std.stdio;
> 
> Or maybe this?
> 
> import std.stdio;
> void foo()
> {
>      import std.stdio;
> }
> 
> Then you said "Implicit conversions could use the same lookup rules", but I'm not sure what you're saying there either.  Maybe if I understood what you meant my "import declarations" then it would make sense?
> ...

Probably. What I mean is multiple imports of different modules:

import std.file;
import std.stdio;

void main(){
    write("hello","world"); // error: ambiguous
}

This is the same situation as:

struct S{
    void write(T...)(string file,T args){ ... }
}
struct T{
    void write(T...)(T args){ ... }
}

struct U{
    S s;
    T t;
    alias s this;
    alias t this;
}

void main(){
    U u;
    u.write("hello","world"); // error: ambiguous
}

Basically any complaint against multiple `alias this` can be turned into a complaint against multiple imports, and all the solutions already exist in D's module system.
« First   ‹ Prev
1 2 3 4 5 6