# Tuples?

The syntax for creating tuple types is defined as:

'(' type (',' tuple)* ')'

In order to create an instance of a tuple we need only separate the individual tuple values with a comma, the syntax being:

expression (',' expression)+

The maximum number of elements within a tuple is 24.

Tuples are an excellent tool for working with collections of typed data, whilst avoiding the need to define a container class specifically to hold it, or by having to use a list. For example:

ageAndName (int, String) = 24, "dave" //a tuple definition
ageAndNameAlt Tuple2<int, String> = 24, "dave" //a tuple definition with alternative mechanism for declaring tuple type
ageAndName2 = 67, "mary" //tuple type is inferred to be (int, String)


Without tuples, the above would have to be captured in the following ways (amongst others):

class AgeAndNameHolder(-age int, -name String)//using a holder object
ageAndName = new AgeAndNameHolder(24, "dave")

ageAndName2 = [67, "mary"] //holding the data within a list


The holder object can become a very heavyweight pattern to use in code, especially for cases where the data lifetime or manipulation context is very short (contained within a method for instance). Likewise, the list pattern is inconvenient as we must remember to explicitly cast got values and it's mutable, meaning the contents can be accidentally changed. Tuples provide a nice middle ground between the two, as much type safety as classes, but with as much convenience in defining as lists.

A nice advantage of tuples is that they are naturally immutable - once created they cannot be changed (note that the objects they contain, if not immutable can be changed).

Tuples are often used for returning multiple values to or from a function or method invocation:

def getAgeAndName(){
return 12, "dave"
}

def getAgeAndName2() (int, String) {//with explicit return type definition
return 12, "dave"
}


Tuples are often used to return multiple values from functions as illustrated in the getAgeAndName2 function above.

## Tuple decomposition?

We can extract values from tuples in one of two ways. We can explicitly refer to the field being extracted:

x = 12, 14
e1 = x.f0
e2 = x.f1


Or we can use a decomposition assignment:

x = 12, 14
e1, e2 = x


If only certain values need to be extracted this can be achieved by simply following the space to ignore with a comma:

x = 12, 14, 15
e1, , e3 = x

//e1 == 12
//e3 == 15


We can make use of the decomposition assignment within for loops like so:

toSum = [(1, 2), (3, 4), (5, 6)]

for(a, b in toSum ) { a + b }
//== [3, 7, 11]


This same effect can be achieved within list comprehensions of tuples:

toSum = [(1, 2), (3, 4), (5, 6)]

(a+b) for a, b in toSum
//== [3, 7, 11]


## Iterating over Tuples?

Tuples support iteration (i.e. can be used in for loops etc):

x = 12, 13
combined = "" + ("el: " + e for e in x)

//combined == "el: 12 el: 13"


## Tuples are Reified Types?

Tuples are reified types, which means that the following is perfectly valid code:

def extractAgeIfNameAndAge(an Object){
if(an is (int, String)){
age, = an
return age
}
-1
}


## Tuples in multiple assignment?

Tuples can be used in multiple assignment statements, e.g:

a, b = c, d = 1, 2

//a == 1
//b == 2
//c == 1
//d == 2


## Tuples in typedefs?

Tuples can be used in typedef statements. E.g.

typedef tuple3 = (int, String, double)
typedef myTuple2<x> = (int, x)//with one parameter: x