2

As I read in When should I choose Vector in Scala?, the question, whether to use List or Vector, receives the same answer in Scala as in Java the question whether to use LinkedList or ArrayList. The answer, as you might know, is "use Vector/ArrayList in most cases".

However, in Scala List is the the ultimate default implementation of Traversable according to http://docs.scala-lang.org/tutorials/FAQ/collections. I guess it's not Vector because "it came late to the party".

  1. Or is there another reason that Vector isn't more dominant?
  2. Wouldn't it make sense to I set IndexedSeq to be the default implementation of Seq and therefore Vector to be the ultimate default implementation of Traversable?
  3. How can I do this?
Community
  • 1
  • 1
Make42
  • 12,236
  • 24
  • 79
  • 155

2 Answers2

3

scala.mutable.Vector based on trie structure so it's technically much more complex than java.util.ArrayList. This complexity means that bunch of Lists sharing commong suffixes could be more lightweight than bunch of Vectors sharing common prefixes.

That property means a lot in functional style where you often have a lot of operations which take collection and return its copy modified just a bit, like stack. Appending to large Vector could generate several new objects, prepeding to List - always one.

List is very simple to understand and reason about. It's just :: or Nil.

Implementation of Vector is pretty much hidden, it has "dirty" optimisations and could be matched preferredly via seq extractors which refers to hidden optimized drops

Random haskell developer probably wants Stream to be default Seq instead of List. Some scalaz lover - wants more some symmetric Sequence exported to std lib.

You can not change choice of scala.Seq.apply becasuse it based on List as result of ListBuffer chosen newBuilder implementation. However you can write your own similar Seq factory like

object Seq extends SeqFactory[Seq] {
  implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
  def newBuilder[A]: Builder[A, Seq[A]] = new VectorBuilder[A]
}

So summarizing:

  1. Linked list is historically most dominant collection type in functional languages
  2. Another sequence type could be much more useful in another domain
  3. You can not "switch" scala.Seq.apply to another generic type. But can import or create another object under name Seq.

I personally find Vector(...) form more useful and concise than IndexedSeq(...). Same for List(...) instead of Seq(...) or LinearSeq(...).

Odomontois
  • 15,918
  • 2
  • 36
  • 71
  • Could you write three little numerated points summarising the answers for my three points? I (think) I get what you're saying (have to ponder about it a bit more), but are not sure what the actual answers are to my questions. – Make42 May 11 '16 at 16:48
1

The "use Vector in most cases" answer that you are used to in java, does not hold in scala, because it is a different language, with different patterns, tools and best practices.

Most structures and variables are immutable, and the algorithms are expressed most of the time in terms of sequentially processing streams of data. With these two observations in mind, one has to conclude that the collection implementation that would best fit most of the use cases is actually a linked list, not a random-access collection.

So, the short answer to your question #3 is "don't do it". A slightly longer version of it is: be explicit. If you think you want to use IndexedSeq in some place, just say so: val seq = IndexedSeq(1,2,3)

Dima
  • 39,570
  • 6
  • 44
  • 70