Thread overview
Trying to get type and name at compile time
May 24, 2016
Edwin van Leeuwen
May 24, 2016
Adam D. Ruppe
May 24, 2016
Edwin van Leeuwen
May 24, 2016
ag0aep6g
May 24, 2016
Edwin van Leeuwen
May 24, 2016
Hi all,

I am trying to get the type and name of a field at compile time, but can't get the following to work. Anyone any idea of why test is not of the type AliasSeq!(double, "x")?


```
import std.meta : AliasSeq;

struct Point { double x; double y; }

alias test = AliasSeq!(
    typeof(__traits(getMember, Point, "x")),
    "x"
);

// I expected AliasSeq!(double,"x")???
pragma(msg,test); // tuple((double), "x")

static assert(is(test == AliasSeq!(double,"x")));

void main() {}
```

Cheers, Edwin
May 24, 2016
On Tuesday, 24 May 2016 at 15:01:33 UTC, Edwin van Leeuwen wrote:
> // I expected AliasSeq!(double,"x")???
> pragma(msg,test); // tuple((double), "x")

What Phobos calls AliasSeq is called tuple inside the compiler. They are the same thing, just different names.

> static assert(is(test == AliasSeq!(double,"x")));

AliasSeq is not comparable as a type. You can test the individual pieces of it (`is(test[0] == double) && test[1] == "x"`) or wrap it in a struct or something.

May 24, 2016
On Tuesday, 24 May 2016 at 15:09:43 UTC, Adam D. Ruppe wrote:
> On Tuesday, 24 May 2016 at 15:01:33 UTC, Edwin van Leeuwen wrote:
>> // I expected AliasSeq!(double,"x")???
>> pragma(msg,test); // tuple((double), "x")
>
> What Phobos calls AliasSeq is called tuple inside the compiler. They are the same thing, just different names.

That's what I assumed at first.. So why does the following fail with: cannot interpret double at compile time? I assumed staticMap would automatically flatten the resulting AliasSeqs.

```
import std.meta : AliasSeq, ApplyLeft, staticMap;

struct Point { double x; double y; }

template addType(T,alias name)
{
    alias addType = AliasSeq!( typeof(__traits(getMember, Point, name)),
        name );
}

alias test3 = addType!( Point, "x" );

// I expected AliasSeq!(double,"x")???
pragma(msg,test3); // tuple((double), "x")

//static assert(is(test == AliasSeq!(double,"x")));
alias ts = AliasSeq!("x","y");
alias addTypeP = ApplyLeft!(addType,Point);
alias mapped = staticMap!(addTypeP,ts);

pragma(msg,mapped);

void main() {
}
```

Looking at it now, I guess it is because staticMap does not work with alias values, only with actual type lists. Is that correct? Any ideas on how to do this?

>
>> static assert(is(test == AliasSeq!(double,"x")));
>
> AliasSeq is not comparable as a type. You can test the individual pieces of it (`is(test[0] == double) && test[1] == "x"`) or wrap it in a struct or something.

I thought so, but a lot of the documentation does seem to compare it (see the example here):
https://dlang.org/library/std/meta/static_map.html



May 24, 2016
On 05/24/2016 06:22 PM, Edwin van Leeuwen wrote:
> That's what I assumed at first.. So why does the following fail with:
> cannot interpret double at compile time? I assumed staticMap would
> automatically flatten the resulting AliasSeqs.
>
> ```
> import std.meta : AliasSeq, ApplyLeft, staticMap;
>
> struct Point { double x; double y; }
>
> template addType(T,alias name)
> {
>      alias addType = AliasSeq!( typeof(__traits(getMember, Point, name)),
>          name );
> }
>
> alias test3 = addType!( Point, "x" );
>
> // I expected AliasSeq!(double,"x")???
> pragma(msg,test3); // tuple((double), "x")
>
> //static assert(is(test == AliasSeq!(double,"x")));
> alias ts = AliasSeq!("x","y");
> alias addTypeP = ApplyLeft!(addType,Point);
> alias mapped = staticMap!(addTypeP,ts);
>
> pragma(msg,mapped);
>
> void main() {
> }
> ```

Seems to be a problem in ApplyLeft:

----
import std.meta: AliasSeq, ApplyLeft;
alias addType(T, string name) = AliasSeq!(T, name);
alias addTypeInt = ApplyLeft!(addType, int);
alias FullyInstantiated = addTypeInt!"foo";
----

Fails with: "std/meta.d(1114): Error: cannot interpret int at compile time".

I've filed an issue:
https://issues.dlang.org/show_bug.cgi?id=16070

[...]
> I thought so, but a lot of the documentation does seem to compare it
> (see the example here):
> https://dlang.org/library/std/meta/static_map.html

Using `is(...)` with an AliasSeq of only types is ok. But you can't use it when there's a non-type in the sequence.
May 24, 2016
On Tuesday, 24 May 2016 at 18:44:45 UTC, ag0aep6g wrote:
>
> Seems to be a problem in ApplyLeft:
>
> ----
> import std.meta: AliasSeq, ApplyLeft;
> alias addType(T, string name) = AliasSeq!(T, name);
> alias addTypeInt = ApplyLeft!(addType, int);
> alias FullyInstantiated = addTypeInt!"foo";
> ----
>
> Fails with: "std/meta.d(1114): Error: cannot interpret int at compile time".
>
> I've filed an issue:
> https://issues.dlang.org/show_bug.cgi?id=16070
>

Thanks! I've worked around it for now with some recursion :)

> Using `is(...)` with an AliasSeq of only types is ok. But you can't use it when there's a non-type in the sequence.

That makes sense.

Thanks for the help, Edwin