Scala Goodness: Tuples

Scala has a wonderful feature: Tuples. As others have already written, tuples are very simple but powerful. Especially if you come from Java, they solve some problems easily, that were ugly in Java.

What are tuples? Tuples are containers for values. In Scala you create a Tuple with:

scala> val t = (1,2)
t: (Int, Int) = (1,2)

which is syntactic sugar for

scala> val t = new Tuple2(1,2)
t: (Int, Int) = (1,2)

as Tuples are plain classes in the Scala library. Tuples are of type Tuple1, Tuple2, Tuple3 and so on. There currently is an upper limit of 22 in the Scala library for creating tuples, which should be enough (as is 640k of RAM). If you need more, then perhaps you really need a collection, not a tuple.

Values in tuples don't need to be of the same type as shown here

scala> val t = (1, "Codemonkeyism")
t: (Int, java.lang.String) = (1,Codemonkeyism)

which is one reason you should not think of them as collections (see below).

After creating a tuple there are several ways of accessing the values:

scala> t
res2: (Int, Int) = (1,2)

scala> t._1
res3: Int = 1

scala> t._2
res4: Int = 2

Beside accessing the values "by index", most often it's more readable to depack tuples into variables. Scala uses extractors for this.

scala> val (x,y) = (1,2)
x: Int = 1
y: Int = 2

Scala matches the unbound variables on the left, x and y, with the values contained in the tuple. If you need only one value, we can read one value if we want

scala> val (x,_) = (1,2)
x: Int = 1

Tuples can be used for returning multiple values from a method - something which is often missed in Java. Side note: Contrary to others I think you should consider creating a class as the return type, if it does contain semantic value and you reuse the type. We define a method which returns two values. Using the depacking from above, we assign each value to its own variable:

scala> def m(a:Int, b:Int) = { (a+b,a-b) }
m: (Int,Int)(Int, Int)

scala> val (s,d) = m(5,8)
s: Int = 13
d: Int = -3

Tuples are not collections. As Jesse Eichar writes:

Tuples are quite handy but a potential annoyance is that at a glance they seem list-like but appearances can be deceiving. The normal collection methods are not supported by Tuples.

He gives some examples how to iterate through tuples though:

scala> (1,2,3).productIterator foreach {println _}            

Another nice hack with Tuples: 1->2 creates a tuple in Scala.

scala> 1->2
res0: (Int, Int) = (1,2)

This is used for creating maps - no need for handling this on a language level like in other languages. As before, this is defined in the Scala library not the language.

scala> val m = Map(1->2, 3->4)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)

Scala glory!