enum and tuples

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Aug 9 10:41:05 PDT 2013


On Fri, Aug 09, 2013 at 09:36:16AM -0700, Ali Çehreli wrote:
> On 08/08/2013 11:16 PM, captaindet wrote:> hi,
> 
> > i am still struggling getting to grips with tuples, especially
> > typetuples.
> 
> Yes, especially TypeTuples. :)
> 
> > typetuples seem to live in a shadow world
> 
> My feelings! :)
> 
> Coincidentally, I am struggling with the same question at the moment
> as I am in the process of revising and translating a Tuples chapter.
> I got stuck just yesterday but I have not re-read Philippe Sigaud's
> document yet.
[...]

According to my understanding (please correct me if I'm wrong), there
are two *different* kinds of tuples, which may be the source of much of
the confusion surrounding tuples.

1) There's the built-in tuple, which is a compiler concept, and
basically means any sequential collections of "things" (for lack of a
better word). For example, you can have a sequence of types, like (int,
string, float), or a sequence of values, like (1, "a", 3.0), or even a
mixture of both, like (1, int, "a", float, string, 3.14). These
sequences are called "tuples".  They have no direct representation in
the language's syntax, but they are an underlying concept that exists in
the language specs and in the compiler. This concept allows us to deal
with variadic functions/templates in a nice way: we abstract away the
list of function/template arguments and say those arguments are tuples,
so then if something else produces or returns a tuple, then we can plug
that in where a parameter list would be expected. This allows us to
construct templates the perform various manipulations on tuples, like
reordering elements, filtering elements, etc.. These "internal tuples",
if you wish to call them that, behave almost like arrays -- they have
.length, and you can dereference them with array indexing notation like
t[0], t[1], which is what happens when you write a variadic function:

	auto f(T...)(T args) {	// args is a tuple containing function arguments
		auto a = args[0]; // a = 1, when called from main() below
		auto b = args[1]; // b = "a"
		auto c = args[2]; // c = 3.14
		auto n = args.length; // n = 3, there are 3 arguments
	}
	void main() {
		f(1, "a", 3.14);
	}

However, unlike arrays, tuples are not full-fledged runtime objects; you
can't manipulate them at runtime like real arrays, and any loop over
them is always unrolled at compile-time (because each tuple element may
be a different type, so it's not possible to have the same loop body in
machine code to process every element).

2) Phobos defines a tuple() function, that wraps an internal tuple of
values inside a struct called Tuple. This allows a nicer interface to
work with tuples of values, since you can explicitly create them, pass
them around like runtime objects, etc.. They are more like structs with
anonymous members, if you like, which are accessed with array indexing
notation. They are NOT the same as internal tuples (though their
implementation uses internal tuples), so you can't pass them to variadic
functions and expect them to behave the same way (though I believe there
*is* a method that returns the internal tuple out of a Tuple struct, so
you can use that to get at the "raw" tuple when you need to).

Phobos' TypeTuples (in std.typetuple), I believe, are basically just an
alias that allows you to explicitly declare and use the internal tuples,
so they are basically the same as (1).

Hope this helps! :)


T

-- 
Guns don't kill people. Bullets do.


More information about the Digitalmars-d-learn mailing list