Tuples¶
This primer demonstrates tuples.
Tuples are a way of grouping several values together. The number of components in each tuple must be known at compile-time. However, unlike an array, a tuple can store components of different types.
Tuples are a language-supported type. Tuples automatically get assignment and comparison operators.
Tuple indices always start at 0.
Getting Started with Tuples¶
The easiest way to create a tuple is with a tuple literal. Tuple literals syntax looks like this:
var myTuple = (1, "two");
Now myTuple
stores a tuple with two elements:
myTuple(0) == 1
and
myTuple(1) == 2
assert(myTuple(0) == 1);
assert(myTuple(1) == "two");
As we saw above, to access an individual tuple element,
use someTuple(i)
or someTuple[i]
. The first tuple
component is at index 0
.
We can assign to a component in our tuple variable
myTuple(1) = "four";
We can print out the tuple. The output format mirrors the Chapel syntax.
writeln(myTuple); // output: (1, four)
Sometimes it’s useful in generic code to query the size of a tuple.
The .size
method returns the size of a tuple.
writeln(myTuple.size); // output: 2
Tuple Types¶
The syntax for tuple types mirrors the tuple literal syntax.
The following line declares a tuple variable storing an int and a string
var otherTuple: (int, string);
We can assign to that tuple from a variable with the same type:
otherTuple = myTuple;
The following line declares a tuple variable holding 3 real values:
var threeReals: 3*real;
writeln(threeReals); // output: (0.0, 0.0, 0.0)
Tuples that have only one component type support some arithmetic on the components:
threeReals += 1.0;
writeln(threeReals); // output: (1.0, 1.0, 1.0)
Tuples with only one component type are also called homogeneous tuples whereas tuples with mixed types are called heterogeneous tuples.
Tuple Iteration¶
Tuples can be iterated over using for loops:
var sum = 0.0;
for r in threeReals {
sum += r;
}
writeln(sum);
In addition, homogeneous tuples can be iterated over using forall and coforall loops.
Heterogeneous tuples can also be traversed using for and coforall
loops. Such loops are always unrolled by the compiler so that each
iteration has its own index variable of the appropriate type. For
example, in the following loop, the index t
of the first
iteration would be of type int
while the index t
of the
second iteration would be of type string
since myTuple
has
type (int, string)
:
for t in myTuple {
writeln(t);
}
Tuple Unpacking¶
Tuple values can be unpacked into variables during variable initialization:
var (myInt, myString) = otherTuple;
writeln(myInt, " ", myString); // output: 1 four
Or assignment:
var x, y, z: real;
(x, y, z) = threeReals;
It’s also possible in for and forall loops:
var ArrayOfTuples: [1..3] (int, real);
for (i,r) in ArrayOfTuples {
i = 1;
r = 0.0;
}
writeln(ArrayOfTuples);
Or in function calls:
proc magnitude( (x,y,z):3*real ) {
return sqrt(x*x + y*y + z*z);
}
threeReals = (1.0, 2.0, 2.0);
var m = magnitude(threeReals);
writeln(m);
Additionally, tuples can be unpacked in the process of making a function call. For example, suppose we have a function accepting individual arguments:
proc add(x, y, z) {
return x + y + z;
}
If we want to pass threeReals to it, we could write
add(threeReals(0), threeReals(1), threeReals(2));
but the tuple can be unpacked at the call site like this:
var total = add( (...threeReals) );
writeln(total);
One-Element Tuples¶
Sometimes one needs to create a tuple storing just one element. To do that, just use the following syntax:
var oneTuple = (1.0,);
writeln(oneTuple);