Bug 10119 – Add tuple overload which automatically captures the names of symbols
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-05-19T11:41:00Z
Last change time
2014-05-22T19:13:06Z
Keywords
pull
Assigned to
andrej.mitrovich
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2013-05-19T11:41:16Z
Currently tuple() can capture the state of local variables and wrap them in a Tuple struct. However you won't have name access:
-----
import std.typecons;
auto foo()
{
int x, y;
return tuple(x, y);
}
void main()
{
assert(foo.x == 0); // fails, no "x"
}
-----
As a workaround you can explicitly name the fields at the call site:
-----
auto foo()
{
int x, y;
return Tuple!(typeof(x), "x", typeof(y), "y")(x, y);
}
-----
But this is tedious and boring, and we can do much better than this. I propose we introduce either an overload of tuple (if it's possible) or a newly named function which automatically wraps the arguments by name into a tuple.
Here's an example implementation:
-----
import std.string;
import std.typecons;
auto tuplify(Aliases...)()
{
string gen()
{
string[] lhs;
string[] rhs;
foreach (idx; 0 .. Aliases.length)
{
lhs ~= format("typeof(Aliases[%s])", idx);
lhs ~= format("__traits(identifier, Aliases[%s])", idx);
rhs ~= format("Aliases[%s]", idx);
}
return format("Tuple!(%s)(%s)", lhs.join(", "), rhs.join(", "));
}
return mixin(gen());
}
auto func()
{
int x = 1;
string y = "2";
return tuplify!(x, y);
}
void main()
{
auto res = func;
assert(res.x == 1);
assert(res.y == "2");
}
-----
Comment #1 by jakobovrum — 2013-05-19T11:55:15Z
No, this instead. (per IRC request)
https://gist.github.com/JakobOvrum/5608585
------------------------------------------
import std.typecons : Tuple;
import std.typetuple : TypeTuple;
template NameTypePairs(alias front, vars...)
{
private enum name = __traits(identifier, front);
private alias pair = TypeTuple!(typeof(front), name);
static if(vars.length == 0)
alias NameTypePairs = pair;
else
alias NameTypePairs = TypeTuple!(pair, NameTypePairs!vars);
}
auto tuplify(vars...)()
{
return Tuple!(NameTypePairs!vars)(vars);
}
Comment #2 by andrej.mitrovich — 2013-05-19T12:00:50Z
(In reply to comment #1)
> No, this instead. (per IRC request)
That one is also faster and more generic-style instead of magic-mixin-style. *Nods head in approval*.
Comment #3 by bearophile_hugs — 2013-05-19T16:10:45Z
I think we should just add tuples to D. I think a possible syntax is tuple(...).
Comment #4 by andrej.mitrovich — 2013-09-18T17:53:05Z
Comment #5 by andrej.mitrovich — 2014-05-22T19:13:06Z
@jcrapuchettes: I have a feeling this may have been something you were looking for when you mentioned named tuples yesterday? Either way it's a small piece of code you can use adapt and right now, so feel free to take it.