Thread overview
how to assign tuple named Tuple easily
Mar 12, 2017
Inquie
Mar 12, 2017
Adam D. Ruppe
Mar 13, 2017
Inquie
Mar 13, 2017
ag0aep6g
Mar 13, 2017
Inquie
Mar 13, 2017
Adam D. Ruppe
Mar 13, 2017
Inquie
Mar 13, 2017
Adam D. Ruppe
Mar 14, 2017
Inquie
March 12, 2017
Tuple!(int, "A") x;

x = tuple(3);

fails of course

x = tuple!("A")(3);

Works but specifying the name seems to be redundant. Can we simplify for the more complex case?

e.g.,

x = tuple!(GetTypleNames!x)(3);

which should then be possible to simplify even further to

x = tuple(3);

or, rather

x = tuple!x(3);

Possible for something like this?



March 12, 2017
On Sunday, 12 March 2017 at 23:16:48 UTC, Inquie wrote:
> Tuple!(int, "A") x;
>
> x = tuple(3);
>
> fails of course

umm it works for me...

March 13, 2017
On Sunday, 12 March 2017 at 23:55:44 UTC, Adam D. Ruppe wrote:
> On Sunday, 12 March 2017 at 23:16:48 UTC, Inquie wrote:
>> Tuple!(int, "A") x;
>>
>> x = tuple(3);
>>
>> fails of course
>
> umm it works for me...

Ok, it doesn't work for appending though ;)

Tuple!(int, "A", double, "B")[] y;
y ~= tuple!("A", "B")(3, 2.5);

vs

Tuple!(int, "A", double, "B")[] y;
y ~= tuple(3, 2.5);

I just figured it didn't work in general, but seems to be an issue with appending.




March 13, 2017
On 03/13/2017 01:02 AM, Inquie wrote:
> Ok, it doesn't work for appending though ;)
[...]
> Tuple!(int, "A", double, "B")[] y;
> y ~= tuple(3, 2.5);

Interestingly, this works:

    Tuple!(int, "A", double, "B")[] y;
    y.length += 1;
    y[$ - 1] = tuple(3, 2.5);
March 13, 2017
On Monday, 13 March 2017 at 00:02:12 UTC, Inquie wrote:
> I just figured it didn't work in general, but seems to be an issue with appending.

Oh, it is because of the implicit construction thing, see my answer here to learn more: http://stackoverflow.com/a/42285015/1457000

You can construct the named tuple from a tuple() but you can't convert one to another since the names change the type.

I don't think the language has a solution with this since you can't implicit construct nor overload operators on built in arrays (if it is a custom array, you can do an opOpAssign).

What you could do is

alias ShortName = Tuple!(int, "A");

ShortName[] a;
a ~= ShortName(3);

... of course, at that point, you can also just use a regular struct too...
March 13, 2017
On Monday, 13 March 2017 at 00:51:27 UTC, Adam D. Ruppe wrote:
> On Monday, 13 March 2017 at 00:02:12 UTC, Inquie wrote:
>> I just figured it didn't work in general, but seems to be an issue with appending.
>
> Oh, it is because of the implicit construction thing, see my answer here to learn more: http://stackoverflow.com/a/42285015/1457000
>
> You can construct the named tuple from a tuple() but you can't convert one to another since the names change the type.
>
> I don't think the language has a solution with this since you can't implicit construct nor overload operators on built in arrays (if it is a custom array, you can do an opOpAssign).
>
> What you could do is
>
> alias ShortName = Tuple!(int, "A");
>
> ShortName[] a;
> a ~= ShortName(3);
>
> ... of course, at that point, you can also just use a regular struct too...


Yeah, so, surely though we can extract the names from the variable and then supply those like I mentioned?

Tuple!(int, "A")[] x;
x ~= tuple!(ExtractTupleNames!x)(3);

which would be equivalent to

x ~= tuple!("A")(3)

which, of course, works.

ExtractTupleNames is a template that surely can get the names from x? Knowing it's type and that every other element of the type is a "name" it should be able to get the names then provide them to tuple? From there, we could redefine tuple to do this automatically as

x ~= tuple!x(3)

? Seems like it would probably be rather trivial with a bit of template code?


Ok, I did this real quick, maybe you can see how to improve it and reduce verbosity:

import std.typecons, std.typetuple, std.meta, std.string, std.array, std.range;

template ExtractTupleNames(T)
{	

	string fix()
	{
		enum q = (T.stringof[7..$-3]);	
		return "alias ExtractTupleNames = AliasSeq!("~q~");";
	}

	mixin(fix());
	
}

void main(string[] argv)
{


	Tuple!(int, "A", double, "B")[] x;

	x ~= tuple!("A", "B")(3, 5.0);
	x ~= tuple!(int, "A", double, "B")(3, 5.0);
	x ~= tuple!(ExtractTupleNames!(typeof(x)))(3, 5.0);
}

The goal would be to not have to specify the long string each time.

e.g., the third line would be either

x ~= tuple!(x)(3, 5.0);

or

x ~= tuple!typeof(x)(3, 5.0);

It would be nice if we could pass a "run time" variable since we are only going to use it's type in the first place(avoids having to specify the typeof at the call point).

I realize that we will probably have to redefine tuple but I'm ok with that as it only makes it more robust.






March 13, 2017
On Monday, 13 March 2017 at 14:09:58 UTC, Inquie wrote:
> Yeah, so, surely though we can extract the names from the variable and then supply those like I mentioned?

Yeah, we prolly could, but a simpler thing might be to just use typeof:

        Tuple!(int, "A")[] x;
        x ~= typeof(x[0])(3);

> x ~= tuple!x(3)
>
> ? Seems like it would probably be rather trivial with a bit of template code?

Yeah, tuple could certainly adapt to do that too, but I see you would write:

> x ~= tuple!typeof(x)(3, 5.0);

and the `tuple!` there is unnecessary: if you already use `typeof(x[0])` (you still need a `[0]` in there to get the type of the element instead of the array), then you can just construct it right there with the next set of parens.
March 13, 2017
On Monday, 13 March 2017 at 00:23:36 UTC, ag0aep6g wrote:
> On 03/13/2017 01:02 AM, Inquie wrote:
>> Ok, it doesn't work for appending though ;)
> [...]
>> Tuple!(int, "A", double, "B")[] y;
>> y ~= tuple(3, 2.5);
>
> Interestingly, this works:
>
>     Tuple!(int, "A", double, "B")[] y;
>     y.length += 1;
>     y[$ - 1] = tuple(3, 2.5);

yeah, seems more like a bug/feature issue. If the compiler can figure it out with assignment, it should also be able to figure it out with appending EXACTLY because what you wrote. Since a default append is effectively the code you wrote above there should be no difference between the two. In fact, I would have hoped that appending built in arrays would have been expanded using the pattern you specifically implemented which should then not produce the error and simplify life.




March 14, 2017
On Monday, 13 March 2017 at 14:15:05 UTC, Adam D. Ruppe wrote:
> On Monday, 13 March 2017 at 14:09:58 UTC, Inquie wrote:
>> Yeah, so, surely though we can extract the names from the variable and then supply those like I mentioned?
>
> Yeah, we prolly could, but a simpler thing might be to just use typeof:
>
>         Tuple!(int, "A")[] x;
>         x ~= typeof(x[0])(3);
>
>> x ~= tuple!x(3)
>>
>> ? Seems like it would probably be rather trivial with a bit of template code?
>
> Yeah, tuple could certainly adapt to do that too, but I see you would write:
>
>> x ~= tuple!typeof(x)(3, 5.0);
>
> and the `tuple!` there is unnecessary: if you already use `typeof(x[0])` (you still need a `[0]` in there to get the type of the element instead of the array), then you can just construct it right there with the next set of parens.

Yeah, I didn't know one could do that. Seems to be better ;) Thanks.