Thread overview
alias this on module
Apr 30, 2017
Jonathan Marler
Apr 30, 2017
Jonathan Marler
May 01, 2017
Jonathan Marler
May 02, 2017
Jonathan Marler
May 05, 2017
Meta
April 30, 2017
Any reason why "alias this" doesn't work at the module level?  If I recall correctly, a module is really just a "class" under the hood, but when I tried to use it I got:

Error: alias this can only be a member of aggregate, not module <module-name>

April 30, 2017
On 4/30/17 7:35 PM, Jonathan Marler wrote:
> Any reason why "alias this" doesn't work at the module level?  If I
> recall correctly, a module is really just a "class" under the hood, but
> when I tried to use it I got:
>
> Error: alias this can only be a member of aggregate, not module
> <module-name>
>

public import is to modules as alias this is to structs/classes :)

-Steve
April 30, 2017
On Sunday, 30 April 2017 at 23:44:32 UTC, Steven Schveighoffer wrote:
> On 4/30/17 7:35 PM, Jonathan Marler wrote:
>> Any reason why "alias this" doesn't work at the module level?  If I
>> recall correctly, a module is really just a "class" under the hood, but
>> when I tried to use it I got:
>>
>> Error: alias this can only be a member of aggregate, not module
>> <module-name>
>>
>
> public import is to modules as alias this is to structs/classes :)
>
> -Steve

They're actually different.

//
// File: mymodule.d
//
module mymodule;

struct Foo
{
    int bar;
    void baz();
}
__gshared Foo foo;
alias foo this; // using "alias this" on a module


//
// File: main.d
//
import mymodule;

// now the symbol "x" refers to foo.x, and the symbol "baz" refers to foo.baz.












May 01, 2017
On 4/30/17 7:59 PM, Jonathan Marler wrote:
> On Sunday, 30 April 2017 at 23:44:32 UTC, Steven Schveighoffer wrote:
>> On 4/30/17 7:35 PM, Jonathan Marler wrote:
>>> Any reason why "alias this" doesn't work at the module level?  If I
>>> recall correctly, a module is really just a "class" under the hood, but
>>> when I tried to use it I got:
>>>
>>> Error: alias this can only be a member of aggregate, not module
>>> <module-name>
>>>
>>
>> public import is to modules as alias this is to structs/classes :)
>>
>
> They're actually different.
>
> //
> // File: mymodule.d
> //
> module mymodule;
>
> struct Foo
> {
>     int bar;
>     void baz();
> }
> __gshared Foo foo;
> alias foo this; // using "alias this" on a module

So you want to alias a struct to a module? That's different than what I thought, I thought you wanted to alias one module's members into another.

I can't see a reason why it couldn't be added as a feature. I admit I'm not seeing the benefit though.

You could simulate this via a mixin. e.g.:

void baz()
{
   foo.baz;
}

@property ref bar()
{
   return foo.bar;
}

-Steve
May 01, 2017
On Monday, 1 May 2017 at 12:41:19 UTC, Steven Schveighoffer wrote:
> On 4/30/17 7:59 PM, Jonathan Marler wrote:
>> On Sunday, 30 April 2017 at 23:44:32 UTC, Steven Schveighoffer wrote:
>>> On 4/30/17 7:35 PM, Jonathan Marler wrote:
>>>> Any reason why "alias this" doesn't work at the module level?  If I
>>>> recall correctly, a module is really just a "class" under the hood, but
>>>> when I tried to use it I got:
>>>>
>>>> Error: alias this can only be a member of aggregate, not module
>>>> <module-name>
>>>>
>>>
>>> public import is to modules as alias this is to structs/classes :)
>>>
>>
>> They're actually different.
>>
>> //
>> // File: mymodule.d
>> //
>> module mymodule;
>>
>> struct Foo
>> {
>>     int bar;
>>     void baz();
>> }
>> __gshared Foo foo;
>> alias foo this; // using "alias this" on a module
>
> So you want to alias a struct to a module? That's different than what I thought, I thought you wanted to alias one module's members into another.
>
> I can't see a reason why it couldn't be added as a feature. I admit I'm not seeing the benefit though.
>
> You could simulate this via a mixin. e.g.:
>
> void baz()
> {
>    foo.baz;
> }
>
> @property ref bar()
> {
>    return foo.bar;
> }
>
> -Steve

Ya now you get it. It's not a big deal, it's just that after I thought about it, I couldn't think of a reason why it's not supported.  I actually have an application for it too.  Since modules are just classes under the hood, I was wondering if implementing it would be as simple as commenting out an error message like Andre's [nested import example](https://www.youtube.com/watch?v=3NihZVcZqto&t=183s&#t=27m15s)
May 01, 2017
On Monday, 1 May 2017 at 21:50:02 UTC, Jonathan Marler wrote:
> On Monday, 1 May 2017 at 12:41:19 UTC, Steven Schveighoffer wrote:
>> On 4/30/17 7:59 PM, Jonathan Marler wrote:
>>> On Sunday, 30 April 2017 at 23:44:32 UTC, Steven Schveighoffer wrote:
>>>> On 4/30/17 7:35 PM, Jonathan Marler wrote:
>>>>> Any reason why "alias this" doesn't work at the module level?  If I
>>>>> recall correctly, a module is really just a "class" under the hood, but
>>>>> when I tried to use it I got:
>>>>>
>>>>> Error: alias this can only be a member of aggregate, not module
>>>>> <module-name>
>>>>>
>>>>
>>>> public import is to modules as alias this is to structs/classes :)
>>>>
>>>
>>> They're actually different.
>>>
>>> //
>>> // File: mymodule.d
>>> //
>>> module mymodule;
>>>
>>> struct Foo
>>> {
>>>     int bar;
>>>     void baz();
>>> }
>>> __gshared Foo foo;
>>> alias foo this; // using "alias this" on a module
>>
>> So you want to alias a struct to a module? That's different than what I thought, I thought you wanted to alias one module's members into another.
>>
>> I can't see a reason why it couldn't be added as a feature. I admit I'm not seeing the benefit though.
>>
>> You could simulate this via a mixin. e.g.:
>>
>> void baz()
>> {
>>    foo.baz;
>> }
>>
>> @property ref bar()
>> {
>>    return foo.bar;
>> }
>>
>> -Steve
>
> Ya now you get it. It's not a big deal, it's just that after I thought about it, I couldn't think of a reason why it's not supported.  I actually have an application for it too.  Since modules are just classes under the hood, I was wondering if implementing it would be as simple as commenting out an error message like Andre's [nested import example](https://www.youtube.com/watch?v=3NihZVcZqto&t=183s&#t=27m15s)

The common thing between modules and the other aggregate types (classes, interfaces, unions and structs) is that members of the former behave as if they were static members of the later. The difference, of course, is that since modules can have only static members, they can't be instantiated and by extension have no 'this' pointer/reference. Because of this I think 'alias member this' on the module level would be nonsensical. Keep in mind that 'alias member this' is a tool for establishing a subtyping relationship - i.e. 'this' instance can be used wherever 'member' can be used - and not just a way to do member access rewrite like opDispatch. There is no subtyping relationship between namespaces, which is what modules are effectively​.

On the other hand, 'alias bar = foo.bar' and module level static opDispatch seem like perfectly reasonable and desirable features.
May 02, 2017
On Monday, 1 May 2017 at 23:06:00 UTC, Petar Kirov [ZombineDev] wrote:
> The common thing between modules and the other aggregate types (classes, interfaces, unions and structs) is that members of the former behave as if they were static members of the later. The difference, of course, is that since modules can have only static members, they can't be instantiated and by extension have no 'this' pointer/reference. Because of this I think 'alias member this' on the module level would be nonsensical. Keep in mind that 'alias member this' is a tool for establishing a subtyping relationship - i.e. 'this' instance can be used wherever 'member' can be used - and not just a way to do member access rewrite like opDispatch. There is no subtyping relationship between namespaces, which is what modules are effectively​.
>
> On the other hand, 'alias bar = foo.bar' and module level static opDispatch seem like perfectly reasonable and desirable features.

It's true that "this" normally refers to an instance of a type, but that's not the case with "alias this".  It's actually referring to the type itself, not an instance, so you can access static members through it.  I've written an example that compiles and works to demonstrate this:

import std.stdio;

struct Foo
{
    int x;
}

struct fakemodule
{
    // a member of the fake module
    // Note that it has to be "static" to be analagous to a real module
    static Foo foo;

    // an "alias this" on the module (this isn't supported on a real module)
    alias foo this;
}

void main()
{
    fakemodule.x = 3; // references fakemodule.foo.x

    // Print x using alias this and direct access
    writeln(fakemodule.x);
    writeln(fakemodule.foo.x);

    // Verify these expressions represent the same thing
    assert(&fakemodule.x == &fakemodule.foo.x);
}
May 05, 2017
On Sunday, 30 April 2017 at 23:35:43 UTC, Jonathan Marler wrote:
> Any reason why "alias this" doesn't work at the module level?  If I recall correctly, a module is really just a "class" under the hood, but when I tried to use it I got:
>
> Error: alias this can only be a member of aggregate, not module <module-name>

It sort of does... almost.

module test3;

void testfun1()
{
}

void testfun2()
{
}

------------------------------------------

module test2;

class Test
{
    public import test3;
}

------------------------------------------

module test1;

import test2;

void main()
{
    Test.test3.testfun1(); //Ok
    Test.test3.testfun2(); //Ok

    import std.stdio;
    import test3;

    assert(&Test.test3.testfun1 == &testfun1); //Passes

    //What?
    Test.testfun1(); Error: no property 'testfun1' for type 'test2.Test', did you mean 'testfun1'?
}

If you add this alias to Test then it will work as expected:

alias testfun1 = test3.testfun1;
May 05, 2017
On 5/5/17 3:37 AM, Meta wrote:
>     //What?
>     Test.testfun1(); Error: no property 'testfun1' for type
> 'test2.Test', did you mean 'testfun1'?
> }
>
> If you add this alias to Test then it will work as expected:
>
> alias testfun1 = test3.testfun1;

Yeah, I'm not sure public importing inside a class/struct is intended to do what you expect. The spec says "All symbols from a publicly imported module are also aliased in the importing module". But it doesn't say anything explicitly about public importing inside a class/struct.

-Steve