www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to assign tuple named Tuple easily

reply Inquie <Inquie data1.com> writes:
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?
Mar 12
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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...
Mar 12
parent reply Inquie <Inquie data1.com> writes:
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.
Mar 12
next sibling parent reply ag0aep6g <anonymous example.com> writes:
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);
Mar 12
parent Inquie <Inquie data1.com> writes:
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.
Mar 13
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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...
Mar 12
parent reply Inquie <Inquie data1.com> writes:
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.
Mar 13
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Mar 13
parent Inquie <Inquie data1.com> writes:
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.
Mar 14