Jump to page: 1 2 3
Thread overview
`alias x = v.x;` not working in struct bodies?
Jan 20
Danilo
Jan 20
Danilo
Jan 20
Danilo
Jan 20
evilrat
Jan 20
Basile B.
Jan 20
Danilo
Jan 20
Danilo
Jan 20
Danilo
Jan 21
Basile B.
Jan 21
Basile B.
Jan 22
Basile B.
January 20

I thought this should easily work, but I was wrong:

module app;
import std;

void main() {
    auto x = new Vec3(10, 20, 30);
}

struct Vec2 {
    int x, y;
}

struct Vec3 {
    Vec2 v;
    alias x = v.x;
    alias y = v.y;

    int   z;

    @disable this();

    this( typeof(x) _x, typeof(y) _y, typeof(z) _z ) { // works
        z = _z; // works

        x   = _x; // error: accessing non-static variable `x` requires an instance of `Vec2`
        v.x = _x; // works

        y   = _y; // error: accessing non-static variable `y` requires an instance of `Vec2`
        v.y = _y; // works

        writeln( x, ", ", y, ", ", z );     // error: accessing non-static variable `a` requires an instance of `Base`
        writeln( v.x, ", ", v.y, ", ", z ); // works
    }

    void func( typeof(x) _x, typeof(y) _y, typeof(z) _z ) { // works
        z = _z; // works

        // doesn't help
        //alias x = this.v.x;
        //alias y = this.v.y;

        x   = _x; // error: accessing non-static variable `x` requires an instance of `Vec2`
        v.x = _x; // works

        y   = _y; // error: accessing non-static variable `y` requires an instance of `Vec2`
        v.y = _y; // works

        writeln( x, ", ", y, ", ", z );     // error: accessing non-static variable `a` requires an instance of `Base`
        writeln( v.x, ", ", v.y, ", ", z ); // works
    }

}

Can't alias targets be used in method bodies?

In the method/constructor parameters it's working as expected. But not inside the bodies?

Documentation:

According to the link alias-variable I would expect my example to work.
Aliasing a variable (struct member), it's a symbol.

January 20

On Saturday, 20 January 2024 at 09:00:22 UTC, Danilo wrote:

>
struct Vec2 {
    int x, y;
}

struct Vec3 {
    Vec2 v;
    alias x = v.x;
    alias y = v.y;
    ...
}

Can't alias targets be used in method bodies?

In the method/constructor parameters it's working as expected. But not inside the bodies?

Documentation:

According to the link alias-variable I would expect my example to work.
Aliasing a variable (struct member), it's a symbol.

We figured it out on Discord. alias works only with static variables and members:

struct Vec2 {
    static int x, y;
}

struct Vec3 {
    static Vec2 v;
    ...

The documentation i mentioned above didn't explicitely say it's for use with static variables/members only.

January 20

All of this advanced stuff in D seems to be implemented for very specific and very limited use cases only.
It could be much more better if it would be implemented for general and broader use cases.

January 20

On Saturday, 20 January 2024 at 10:00:15 UTC, Danilo wrote:

>

All of this advanced stuff in D seems to be implemented for very specific and very limited use cases only.
It could be much more better if it would be implemented for general and broader use cases.

In your vec3 example, while it is tempting to automate this using cool smart features, you will end up regretting using it.

And in this example you can use union to join vec2 and add extra synonyms members.
I see there is a lot of libraries that using similar smart metaprogramming for basic types in D, but when I tried to do "smart" things using alias this in the end I often got bitten by it and regretting using templates and stuff.

Alias this has annoying property to mess up with your RAII wrappers.
The fancy metaprogramming engineering results in poor IDE experience and slower compilation(neglectible in this case) times along with even more horrible debugging.

struct Vec3 {

    union {
        struct {
            float x = 0;
            float y = 0;
            float z = 0;
        }
        struct {
            Vec2 _xy;
            float _z;
        }
        float[3] values;
    }

    // ...
}
January 20

On Saturday, 20 January 2024 at 09:49:06 UTC, Danilo wrote:

>

On Saturday, 20 January 2024 at 09:00:22 UTC, Danilo wrote:

>

Documentation:

According to the link alias-variable I would expect my example to work.
Aliasing a variable (struct member), it's a symbol.

We figured it out on Discord. alias works only with static variables and members:

struct Vec2 {
    static int x, y;
}

struct Vec3 {
    static Vec2 v;
    ...

The documentation i mentioned above didn't explicitely say it's for use with static variables/members only.

You can't alias fields of an aggregate type instance outside of the type definition. You can alias members of an aggregate type, such as static member variables. You can alias non-static members inside the aggregate definition.

struct S
{
    int j;
    alias k = j;
}

I'll look at updating the spec as you're right, it's not clear.

BTW I have a PR which deprecates aliasing a member of a type instance:
https://github.com/dlang/dmd/pull/15863

I added a test case similar to your example.

January 20

On Saturday, 20 January 2024 at 13:39:37 UTC, Nick Treleaven wrote:

>

I'll look at updating the spec as you're right, it's not clear.

https://github.com/dlang/dlang.org/pull/3758

January 20

On Saturday, 20 January 2024 at 13:39:37 UTC, Nick Treleaven wrote:

>

You can't alias fields of an aggregate type instance outside of the type definition.

It's not an alias of some arbitrary symbol. The field is accessible through 'this' of the deriving struct, and it is reasonable to expect it should be accessible though an alias in the context of that 'this'.

January 20

On Saturday, 20 January 2024 at 14:56:52 UTC, Max Samukha wrote:

>

It's not an alias of some arbitrary symbol. The field is accessible through 'this' of the deriving struct, and it is reasonable to expect it should be accessible though an alias in the context of that 'this'.

Disregard that. I assumed there was 'alias this' in the OP's example. Now the question is, should this work:

struct S
{
    int x;
}

struct S2
{
    S s;
    alias this = s;
    alias x = S.x;
}

auto x = S2().x; // Error: need 'this'

?

January 20

On Saturday, 20 January 2024 at 15:34:59 UTC, Max Samukha wrote:

>

Disregard that. I assumed there was 'alias this' in the OP's example. Now the question is, should this work:

struct S
{
    int x;
}

struct S2
{
    S s;
    alias this = s;
    alias x = S.x;
}

auto x = S2().x; // Error: need 'this'

?

alias this is used as a fallback for member lookup when no symbol with the requested name exists. Since you declared a symbol named x in S2, there is no need to fall back to alias this when attempting to look up S2().x.

January 20

On Saturday, 20 January 2024 at 15:55:13 UTC, Paul Backus wrote:

>

alias this is used as a fallback for member lookup when no symbol with the requested name exists. Since you declared a symbol named x in S2, there is no need to fall back to alias this when attempting to look up S2().x.

Arguable but I don't have the energy to argue. Let it be.

« First   ‹ Prev
1 2 3