When do you choose to type a given function\'s return type as Seq vs Iterable vs Traversable (or alternatively even deeper within Se
Seq by default everywhere.IndexedSeq when you need to access by index.These are the "common-sense" guidelines. They are simple, practical, and work well in practice while balancing principles and performance. The principles are:
Seq satisfies both principles. As described in http://docs.scala-lang.org/overviews/collections/seqs.html:
A sequence is a kind of iterable that has a [finite] length and whose elements have fixed index positions, starting from 0.
90% of the time, your data is a Seq.
Other notes:
List is an implementation type, so you shouldn't use it in an API. A Vector for instance can't be used as a List without going through a conversion.Iterable doesn't define length. Iterable abstracts across finite sequences and potentially infinite streams. Most of the time one is dealing with finite sequences so you "have a length," and Seq reflects that. Frequently you won't actually make use of length. But it's needed often enough, and is easy to provide, so use Seq.Drawbacks:
There are some slight downsides to these "common-sense" conventions.
case head :: tail => ... . You can use :+ and +: as described here. Importantly, however, matching on Nil still works as described in Scala: Pattern matching Seq[Nothing].Footnotes:
Map here because the question, sensibly, doesn't ask about it.