On Thursday, 6 January 2022 at 13:18:56 UTC, Timon Gehr wrote:
>BTW, it should work like this:
void foo(string x){} // <- a string, not a tuple
void foo(string x,){} // <- unary tuple
void foo((string,) t){} // <- unary tuple
void foo(string x,int y){} // <- 2-tuple
void foo((string,int) t){} // <- 2-tuple
So perhaps your example would not even work that way; unary tuples shouldn't decay into the underlying type. The concept will need some fleshing out. Maybe it's indeed too hard to actually retrofit this into the language...
Actually I think you were on the right track in your earlier post, with this example:
void foo(int a, string b){} // pattern (int a,string b)
foo(1,"2"); // match tuple (1,"2")
i.e., the argument list itself should be treated like a tuple, and one could also write
auto tup = (1, "2");
foo(tup);
In fact, this is how tuples already work in D, just with nicer syntax--(1, "2")
instead of tuple(1, "2").expand
.
What the current language can't do, without using wrapper structs like std.typecons.Tuple
, is nest tuples. In other words, the question we need to answer is perhaps better framed as "when aren't tuples expanded?"