Jump to page: 1 2
Thread overview
Making alias of a struct field needs "this".
Jun 02, 2020
realhet
Jun 02, 2020
Basile B.
Jun 02, 2020
Basile B.
Jun 02, 2020
Ali Çehreli
Jun 02, 2020
realhet
Jun 02, 2020
realhet
Jun 02, 2020
Paul Backus
Jun 02, 2020
realhet
Jun 03, 2020
realhet
Jun 03, 2020
realhet
Jun 02, 2020
Stanislav Blinov
Jun 02, 2020
realhet
June 02, 2020
Hello,

I have a 2 level nested struct structure with nice descriptive field names.
And I thought it will be easy to alias those identifierLists with a few letter names and do some calculations on them.
But I'm having an error.

struct A{
  struct B{ int c; }
  B b;

  auto f(){
    alias d = b.c;
    return d;  //Compiler Error: need 'this' for c of type int.
  }
}

There's the this and it's called "b."

Why is this? If I copy paste the aliased expression "b.c", it compiled fine.

Thanks in advance!

June 02, 2020
On Tuesday, 2 June 2020 at 08:56:13 UTC, realhet wrote:
> Hello,
>
> I have a 2 level nested struct structure with nice descriptive field names.
> And I thought it will be easy to alias those identifierLists with a few letter names and do some calculations on them.
> But I'm having an error.
>
> struct A{
>   struct B{ int c; }
>   B b;
>
>   auto f(){
>     alias d = b.c;
>     return d;  //Compiler Error: need 'this' for c of type int.
>   }
> }
>
> There's the this and it's called "b."
>
> Why is this? If I copy paste the aliased expression "b.c", it compiled fine.
>
> Thanks in advance!

There's a language rule, expressions cant be aliased, however D has a bug, some expressions
that look like type can be aliased, then when you use them you have an error about 'this' but in first place here you should really have an error saying 'cant alias expression'.
June 02, 2020
On Tuesday, 2 June 2020 at 09:07:08 UTC, Basile B. wrote:
> On Tuesday, 2 June 2020 at 08:56:13 UTC, realhet wrote:
>> [...]
>
> There's a language rule, expressions cant be aliased, however D has a bug, some expressions
> that look like type can be aliased, then when you use them you have an error about 'this' but in first place here you should really have an error saying 'cant alias expression'.

Note that most of the time attempts to alias expressions is detected. This is a particular bug, a "corner case".
June 02, 2020
On 6/2/20 1:56 AM, realhet wrote:

> struct A{
>    struct B{ int c; }
>    B b;
>
>    auto f(){
>      alias d = b.c;

The spec explicitly says it's not legal: "Aliases cannot be used for expressions" (Item 10):

  https://dlang.org/spec/declaration.html#alias

I use nested functions for such cases:

  auto f(){
    auto d() {
      return b.c;
    }
    return d;
  }

Ali

June 02, 2020
On Tuesday, 2 June 2020 at 09:10:03 UTC, Ali Çehreli wrote:
> On 6/2/20 1:56 AM, realhet wrote:
>
> > struct A{
> >    struct B{ int c; }
> >    B b;
> >
> >    auto f(){
> >      alias d = b.c;
>
> The spec explicitly says it's not legal: "Aliases cannot be used for expressions" (Item 10):
>
>   https://dlang.org/spec/declaration.html#alias
>
> I use nested functions for such cases:
>
>   auto f(){
>     auto d() {
>       return b.c;
>     }
>     return d;
>   }
>
> Ali

Thanks for responses:

I did it that way:
  private enum fieldMap = [ // simple names for descriptive and structured fields
    "hauteur"       : "general.height",
    "rayon"         : "profile.radius",
    "plage"         : "profile.plage",
    "offsetv"       : "profile.verticalOffset",
    "offseth"       : "profile.horizontalOffset",
    "varrad0"       : "profile.linearVariationBottom",
    "varrad1"       : "profile.linearVariationTop",
    "amplitude"     : "periphery.amplitude",
    "varlin0"       : "periphery.linearVariationBottom",
    "varlin1"       : "periphery.linearVariationTop",
    "varsinp"       : "periphery.cosinusVariationPlage",
    "varsino"       : "periphery.cosinusVariationOffset",
    "periodes"      : "periphery.nbPeriods",
    "revolution"    : "periphery.turn"
  ];

  static foreach(k, v; fieldMap){ mixin("@property auto $() const{ return #; }".replace("$", k).replace("#", v)); } //I know, i know -> AliasSeq :D

But it doesn't look nice.

I've found some additional info here: https://forum.dlang.org/thread/hresorfqicczofnrccpl@forum.dlang.org?page=2

Seems like I must not except the same from an alias template paramater and from the alias construct. The alias construct is for a single symbol.
June 02, 2020
On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:
> On Tuesday, 2 June 2020 at 09:10:03 UTC, Ali Çehreli wrote:
>> On 6/2/20 1:56 AM, realhet wrote:

Oh and I can put that function generator mixin thing into a template as well, that way it is reusable and much nicer.

There are a lot of possibilities in D, I love it!
June 02, 2020
On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:
>
>   static foreach(k, v; fieldMap){ mixin("@property auto $() const{ return #; }".replace("$", k).replace("#", v)); } //I know, i know -> AliasSeq :D

You can use std.format.format to do it in one function call:

    mixin("@property auto %s() const { return %s; }".format(k, v));

Or just put `k` and `v` directly into the mixin:

    mixin("@property auto ", k, "() const { return ", v, "; }");
June 02, 2020
On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:

> I did it that way:
>   private enum fieldMap = [ // simple names for descriptive and structured fields
>     "hauteur"       : "general.height",
>     "rayon"         : "profile.radius",
>     "plage"         : "profile.plage",
>     "offsetv"       : "profile.verticalOffset",
>     "offseth"       : "profile.horizontalOffset",
>     "varrad0"       : "profile.linearVariationBottom",
>     "varrad1"       : "profile.linearVariationTop",
>     "amplitude"     : "periphery.amplitude",
>     "varlin0"       : "periphery.linearVariationBottom",
>     "varlin1"       : "periphery.linearVariationTop",
>     "varsinp"       : "periphery.cosinusVariationPlage",
>     "varsino"       : "periphery.cosinusVariationOffset",
>     "periodes"      : "periphery.nbPeriods",
>     "revolution"    : "periphery.turn"
>   ];
>
>   static foreach(k, v; fieldMap){ mixin("@property auto $() const{ return #; }".replace("$", k).replace("#", v)); } //I know, i know -> AliasSeq :D
>
> But it doesn't look nice.

Try UDAs instead of a map:

struct A {
    struct G {
        @("hauteur") int height;
    }
    struct P {
        @("rayon")   int radius;
        @("plage")   int plage;
        @("offsetv") int verticalOffset;
        @("offseth") int horizontalOffset;

        int noShortcut;

        @("varrad0") int linearVariationBottom;
    }

    G general;
    P profile;
    /* ... */
    static foreach (i, m; typeof(this).tupleof)
        static foreach (j, f; typeof(m).tupleof)
            static if (__traits(getAttributes, f).length)
                mixin("@property auto ", __traits(getAttributes, f)[0], "() const { return this.tupleof[i].tupleof[j]; }");
}

pragma(msg, __traits(allMembers, A));

June 02, 2020
On Tuesday, 2 June 2020 at 13:10:55 UTC, Paul Backus wrote:
> On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:
>     mixin("@property auto ", k, "() const { return ", v, "; }");

Wow, string mixin can process comma separated list, I gotta remember this, thanks!


June 02, 2020
On Tuesday, 2 June 2020 at 13:37:25 UTC, Stanislav Blinov wrote:
> On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:
> Try UDAs instead of a map:
>
> struct A {
>     struct G {
>         @("hauteur") int height;
>     }

Good idea, thx! I already using UDA's for range and measurement units.

  struct Profile{ @STORED:
    @UNIT("mm")     @RANGE(0, 100)  float radius = 21;

I gonna need one more reasonably named UDA struct.
« First   ‹ Prev
1 2