What are tuples exactly? (D's tuples considered harmful)

%u wfunction at hotmail.com
Fri Feb 25 17:06:25 PST 2011


>> Anyway, at some point I realized that I cannot understand what is going on because there is some language mechanism in action
which I do not know.

> Fuck no! "precise definition of tuples" is something that always makes me really grumpy. Do we want a incomprehensible ivory tower
language or something practical? The D's tuples are a bit hazy. A bit harder to grok, but the good sides are better performance,
flexibility and friendliness towards pragmatic c/c++ mentality. If you want something "better", go use Haskell an enjoy your 90%
slower runtimes.

Lol.
I think I'll try to explain tuples, since I feel kind of bad just taking from the community but not giving back. :) So here's an
explanation for those who are new to the concept:

--------------

The word "tuple" is used with two _very_ different meanings in D: compile-time tuples and run-time tuples. So let's split them up.


- Run-time tuples are located in std.typecons, and are pretty much C++ templates that let you create a data type called a "Tuple".
That's it. Aside from the fact that you can actually specify the field names, there's no more to them than their equivalents in C++
(0x). So Tuple!(int, "a", long, "b") is just a shorthand way of making a data type that bundles two int's and long's together, and
it names the fields "a" and "b'. Pretty simple.


- Compile-time tuples are a COMPLETELY different beast. They don't require any external modules (they're purely a compile-time
feature), although std.typetuple is useful when working with them.
You can think of a tuple as "a bunch of things separated by commas". These "things" can be types, numbers, strings, or aliases
(which refer to other things).

The declaration of std.typetuple.TypeTuple is actually pretty straightforard, but it takes a bit of getting used to:

	template TypeTuple(T...)
	{
	    alias T TypeTuple;
	}

What exactly does this do? It creates a template with any number of "things" as arguments, then gives them the name TypeTuple as a
whole. To see what I mean, look at this code:

	foreach (T; TypeTuple!(int, bool, string))
	{
		writeln(T.init);
	}

This code iterates through every parameter given to TypeTuple -- namely, it iterates through the types int, bool, and string --
making T represent the parameter, and it generates code for the inside of the loop, just like a regular for loop would.

Except that this code is generated AT COMPILE TIME!

Contrary to its, name, a TypeTuple can actually be a tuple of any "thing" -- you can also give it strings, numbers, etc. So you
could also do something like:

	foreach (V; TypeTuple!(0, false, "Hello"))
	{
		writeln(V);
	}

and it would print just what you expect.


You can make a function called myWriteLine, which prints everything but the first and last parameters:

	void myWriteLine(T...)(T items)
	{
		writeln(items[1 .. $ - 1]);  //1 is the first index you want, "$ - 1" is the last index you DON'T want
	}

This powerful idea is extended in a variety of ways, and it ultimately lets you generate a lot of code at compile-time that you
would find difficult or impossible to generate in other languages, or that, if possible, would otherwise happen at runtime. It's
truly a beast, and I've barely shown any of its power here. :)



Hope that helped.


More information about the Digitalmars-d mailing list