the blog for developers

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 _}
1
2
3

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!

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

About the author: Stephan Schmidt has more than 15 years of internet technology experience and 10 years experience in agile. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own.

7 Tweets

Leave a reply.

Comments

Richard

Hi Stephan, since your English is already so good, you might as well aim for 100% by correcting your use of “its” versus “it’s”

http://www.askoxford.com/asktheexperts/faq/aboutgrammar/apostrophe

Keep up the excellent writing!

Zach Cox

There’s an implicit method in Predef that provides the a->b Tuple2 creation trick:

http://www.scala-lang.org/docu/files/api/scala/Predef$object.html#any2ArrowAssoc%28A%29

any2ArrowAssoc wraps a in a new ArrowAssoc object, and then ArrowAssoc’s -> method returns Tuple2(a,b). Pretty slick!

ArrowAssoc also has a → method which should render as a Unicode arrow, which is interesting.

“ArrowAssoc also has a → method which should render as a Unicode arrow, which is interesting.”

Didn’t know – nice.

@Richard: Shame on me, I will try harder in the future. When thinking about it I know the when to use “its” vs. “it’s” – but not when I’m writing. More quality next time. Promised.

@Richard: And thanks for “Keep up the excellent writing!”

Jamie

I do enjoy coding in Scala, and I’m fortunate enough to be employed on a project that utilizes the language. However, I think tuples are a dangerous toy. Anyone using a tuple is inherently coupled with the entity that returned it, because you have to know exactly what is in it at each of its values.

This is a form of execution connascence, and that bothers me.

dan

handy for scripting/glue code, but i really don’t like the idea of using this sort of construct in any language where you can define an object.

in your examples above, it really isn’t ever clear what those numbers actually represent. a lot nicer to make a Vector2 class, or a ReturnValues class or something, to actually represent what each of those numbers mean.

@Dan, @Jamie: As I worte: “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.”

Luc

Tuple rocks !
What a shame to return a List when you know you will always return two elements !

Jamie

Stephan – Yep. I will admit that I do use tuples (because they’re darned handy), I just felt a little dirty doing it.

Also, I was wrong. It’s connascence of position. Here’s Jim Weirich’s definition: http://onestepback.org/articles/connascence/conposition.html

I’d never heard of connascence until Jim’s presentation at the Software Craftsmanship NA conference in August.

Good stuff. Thanks.

The ._1 syntax is pretty ugly, IMO but there wasn’t much that could be done, I suppose. I think Tuples are great when you need multiple return values; the Java way is an array of Object (ugh).

Also, FWIW, I wrote a blog post deconstructing how the “map literal” works, wrt to ArrowAssoc and Tuples, for anyone interested:

http://www.naildrivin5.com/blog/2009/11/12/deconstructing-scala-map-literal.html

http://www.naildrivin5.com/blog/2009/11/24/scalas-map-literal-as-a-prezi.html

Mirko

Coming from a python background I know the power of lists and tuples. However nowadays I consider them as a bit dangerous having seen tuples abused in constructs like:
if e[6][7][8] == 2:
do something
where a real object would have been a better solution.
Regards
Mirko

@Mirko: +1

@Dave: I consider the ._1 syntax also ugly

usr

@”tuple fear”:

Using tuples instead of proper domain classes isn’t that much of a problem – as long as your tuple members are proper domain types and not just raw primitives.

If i’d have a choice between Pair[Bar, Baz] than class Foo(bar:Int, baz:Int) i’d take the tuple without hesitation.

Most value-carrier classes are defined pretty well by the types of their members, provided the member types are meaningful. Slapping a name tag to that composition of member types is only a convenience (or waste of time, some might argue), as long as that specific composition of member types is unique in that there is no need to partition the set of instances of that specific composition of member types into multiple classes.

It even happened on this blog: http://codemonkeyism.com/never-never-never-use-string-in-java-or-at-least-less-often/

Thinking further along this line i think it really is sad that Scala does not provide a way to specialize from final classes (or maybe that possibility exists and i just don’t know about it, which would give the sadness a more local scope). Of course subtyping from final types would have to be limited to “straight” subclassing (not adding or changing structure or behaviour), but it would be just so very handy for semantic types like FirstName or LastName. It wouldn’t even be a big loss if those “straight subtypes” would fall victim to erasure, as their main utility would be at compile time (and this limitation could make it possible to keep the instances-of-primitive-classes-are-primitives-at-runtime magic in place for subtypes of, say, Int, which would certainly be of biggest importance).

I’m sure Scala has some very nice tricks to emulate subtyping from from finals (just think of what RichString does), but that would open the gates for structural/behavioral changes as well which might not be so good. Also, there is little chance for transparent suptyped primitives that way.

usr

That certainly should have been:

“If i’d have to chose between Tuple2[Bar, Baz] and case class Foo(bar:Int, baz:Int) i’d take the tuple variant without hesitation, all the time.”

The rest of the post was meandering ramblings anyway.

I use tuples quite a bit internally – i.e. in private functions – especially when it is necessary to return two or more values from one function to another. However, I avoid using tuples at the interfaces between components (classes/objects) because I think the interfaces at these boundaries need to be more self-descriptive than just “a pair of things”. I’d use a strong type at these points, and would always try to avoid returning two things from a public function.

Leave a Reply

What people wrote somewhere else:

Published new blog post: “Scala Goodness: Tuples” http://ow.ly/1mTCiR #scala

This comment was originally posted on Twitter

RT @codemonkeyism: Published new blog post: “Scala Goodness: Tuples” http://ow.ly/1mTCiR #scala

This comment was originally posted on Twitter

Scala Goodness: Tuples http://ff.im/-e8K50

This comment was originally posted on Twitter

RT @codemonkeyism: Published new blog post: “Scala Goodness: Tuples” http://ow.ly/1mTCiR #scala

This comment was originally posted on Twitter

Scalaのタプルの紹介。Javaだと自作するか、Map.Entryになるのかな。 Code Monkeyism: Scala Goodness: Tuples http://bit.ly/4sJGUW

This comment was originally posted on Twitter

http://tinyurl.com/yev8spr Scala Goodness: Tuples

This comment was originally posted on Twitter

RT @codemonkeyism Code Monkeyism: Scala Goodness: Tuples http://bit.ly/5JfFEF

This comment was originally posted on Twitter

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?