Tuple Types
A tuple is a well-defined group of values of specific types that can be handled together as a single grouped value, and also be taken apart into their individual values easily. Tuples provide a more lightweight way to group related values without the need of declaring, for example, an explicit Record type.
A tuple type is expressed with the tuple of
keywords, followed by a list of two or more types (since a tuple of just one value makes very little sense).
method ExtractValues(s: String): tuple of (String, Integer);
The method declared above would return a tuple consisting of a String and an Integer.
A tuple value can be constructed simply by providing a matching set of values surrounded by parentheses. The following result
assignment would work for the above method.
result := ("A String", 5);
Tuple values can be assigned in whole or as their individual parts, both when assigning from a tuple or to one:
var t: tuple of (String, Int);
var s: String := "Hello"
var i: Integer := 5;
t := (s, i); // assigning individual values to a tuple
var u := t; // assigning one tuple to another
(s, i) := ExtractValues("Test"); // assigning a tuple back to individual elements
Extracting a tuple back to individual items can even be combined with a var
Statement, to declare new variables for the items:
var t := ExtractValues("Test");
var (a, b) := ExtractValues("Test"); // assigning a tuple back to individual elements
Here, three new variables are declared. For the first call, t
is declared as new tuple variable, so far so unusual. For the second call though, two new variables a
and b
are declared, and the tuple is automatically taken apart, so that a
would hold the String value and b
the Integer.
Tuples and Discardable
Tuple extraction can also be combined with a [Discardable] Expression(../Expressions/Discardable). If only some of the values of a tuple are of interest, the nil
keyword can be provided in place of the items that are not of interest, and the will be discarded.
var (FirstName, nil, Age) := GetFirstNameLastNameAndAge();
Here, assuming that GetFirstNameLastNameAndAge
returns a tuple of three values of information about a person, but only two variables are declared, for the FirstName
and Age
, the middle value of the tuple is simply discarded.
Accessing Individual Tuple Items
Instead of extracting the whole tuple, individual values inside a tuple can also be accessed directly, with the Indexer Expression:
var Info := GetFirstNameLastNameAndAge();
writeLn($"{Info[0]} is {Info[2]" years old".)
While in syntax this access looks like an array access, the access to to each item of the tuple is strongly typed, so Info[0]
is treated as a String, and Info[2]
as an Integer, for this example. For this reason, a tuple can only be indexed with a constant index.
Named Tuples
Tuples can optionally be defined to provide names for their values. Either all or none of the values need to have a name, a tuple cannot be "partially named". A named tuple can be initialized with a tuple literal with or without names.
var Person: tuple of (Name: String, Age: Integer);
Person := (Name := "Peter", Age := 25);
Person := ("Paul", 37);
In a named tuple, individual items can be accessed both via index as outlined above, and via name:
writeLn($"{Person.Name} is {Person[1]" years old".)
Named and unnamed tuples (and tuples with mismatched names) are assignment compatible, as long as the types of the tuple items matches.
var Person: tuple of (Name: String, Age: Integer);
var Person2: tuple of (String, Integer);
Person := Person2;
Person2 := Person;
See Also
- Discardable Expression