A Discussion of Tuple Syntax

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Aug 19 18:05:00 PDT 2013


On Tue, Aug 20, 2013 at 02:40:00AM +0200, Meta wrote:
> On Tuesday, 20 August 2013 at 00:29:17 UTC, H. S. Teoh wrote:
> >Sounds like you're confused about what built-in tuples are (and
> >you wouldn't be the first -- they're rather confusing things).
> 
> I know the difference between std.typecons.Tuple and the built-in
> tuples. What I'm confused about is I thought that the main objective
> of the tuple literal syntax (destructuring/pattern matching aside)
> was a means to have first-class tuples. That is, tuples that have
> their own literal syntax, have a list of valid operations that can
> be done on them, can be passed to functions, and can be returned
> from functions.

Actually, reading through DIP32 again, it sounds like Kenji is proposing
the *same* syntax for both built-in tuples and std.typecons.Tuple. In
the code example under "Generic type/expression tuple syntax", he refers
to them respectively as "tuple type" and "tuple value". Mixing is also
allowed (e.g., in the "alias Fields" line).

So it sounds like this is similar to what bearophile was suggesting --
the unification of built-in tuples and Phobos Tuples. I suppose the
intention is that if a built-in tuple like (1, "a", 1.0) is used as a
value, it would be automatically translated into a runtime tuple value.
I'm not sure if the reverse is possible, though, since if the tuple
contains some runtime values, then it's not possible to translate it
back into a built-in tuple.

Actually, going in either direction requires some restrictions; for
example, if a tuple contains a type, like (1, int), then it's impossible
to translate it into a runtime tuple (types have no runtime value in and
of themselves). Similarly, if a tuple contains a runtime variable, then
it's impossible to use it as a compile-time tuple. But if a tuple
contains only compile-time known values, then it's in theory usable both
as a built-in tuple and a runtime tuple.

There might be some areas where this conflation may cause trouble,
though; for example, if you have a tuple (1, x) where x is a runtime
variable, then should it be treated as (1, {alias of x}) or (1, {runtime
value of x})? The former would happen if you pass it to a template that
expects an int and and alias parameter, for example, and the latter if
you try to store this tuple into a variable. It may lead to this weird
situation:

	template Tmpl(int x, alias y) { ... }
	int x=123;
	auto tup = {1; x};
	alias T = Tmpl!tup;	// OK, 1 -> int x, x -> alias y
	auto tup2 = tup;	// store {1;123} into variable
	alias U = Tmpl!tup2;	// ERROR: cannot instantiate template with runtime variable

Actually, looking at this again, it seems the problem is with the "tup =
{1; x}" line. Does {1; x} in the above code mean {1; 123}, or does it
mean {1; {alias of x}}? For example, if you wrote this:

	int x=123;
	auto tup = {1; x};
	x++;
	writeln(tup);

What should be the output? Should the output change if the second line
is changed to:

	alias tup = {1; x};

?


T

-- 
A mathematician is a device for turning coffee into theorems. -- P. Erdos


More information about the Digitalmars-d mailing list