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 1.
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(1) == 1
and
myTuple(2) == 2
assert(myTuple(1) == 1);
assert(myTuple(2) == "two");
As we saw above, to access an individual tuple element,
use someTuple(i)
or someTuple[i]
. The first tuple
component is at index 1
.
We can assign to a component in our tuple variable
myTuple(2) = "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.
Tuple Iteration¶
Tuples with only one component type can be iterated over using a for loop:
var sum = 0.0;
for r in threeReals {
sum += r;
}
writeln(sum);
To iterate over a tuple with multiple component types, use a
for param
loop.
This kind of loop is always unrolled by the compiler so the loop body can
use different types in different iterations.
for param i in 1..myTuple.size {
writeln("myTuple(", i, ") = ", myTuple(i));
}
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(1), threeReals(2), threeReals(3));
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);