Why is VectorBuilder in the package scala.collections.immutable?

collections, scala

Solution

`VectorBuilder` is not meant to be used directly. If you want to get a builder for a `Vector`, you only need to call `Vector.newBuilder[T]`, which returns a `Builder[T, Vector[T]]` (with the underlying instance being a `VectorBuilder`).

So if you want the default builder that would be used to create a `Seq`, you only need to call `Seq.newBuilder`:

scala> Seq(1,2,3)
res0: Seq[Int] = List(1, 2, 3)

scala> Seq.newBuilder[Int]
res1: scala.collection.mutable.Builder[Int,Seq[Int]] = ListBuffer()

scala> Seq.newBuilder[Int].result
res2: Seq[Int] = List()

The above shows that the default implementation of `Seq` is list, and, logically, the default builder for a `Seq` is actually a `mutable.ListBuffer`.

`ListBuffer` is more than just a `List` builder, that's why it is in `collection.mutable` whereas `VectorBuilder` is not a `Buffer`, it cannot be used for anything else other than build a `Vector`. That's probably why it is defined locally in `Vector`. I am not sure why it isn't `private`, I cannot see it referenced anywhere in the public API of `Vector` itself. Maybe it should be (private).

Just for reference, there is no hidden magic happening with `CanBuildFrom`, it almost always just goes through the `newBuilder` above:

When you do not specify the expected collection type, as in `Seq(1,2).map(_+1)`, the only available `CanBuildFrom` comes from the companion object a `Seq`, and is of type `CanBuildFrom[Seq[_], T, Seq[T]]`. That means the result will be a `Seq` too.

Like most companion objects of collections, the `CanBuildFrom` instance `Seq` provides only does one thing: call `Seq.newBuilder` (that's defined in GenTraversableFactory ...)

That's why `CanBuildFrom` for `Vector` uses a `VectorBuilder`. For example, in this:

scala> Vector(1,2,3).map(_+1)
res12: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)

The builder that was used is:

scala> implicitly[CanBuildFrom[Vector[Int], Int, Vector[Int]]].apply()
res13: scala.collection.mutable.Builder[Int,Vector[Int]] = 
  scala.collection.immutable.VectorBuilder@43efdf93

Problem

`VectorBuilder` is defined in the same source file as `Vector`. `Vector` is immutable and in the scala.collections.immutable package, so as a consequence the builder is in the same package. As far as I can tell, `CanBuildFrom` uses a `VectorBuilder` as the default, if the return type is not explicitly typed. - Is there a reason for not having the builder in a separate file in the mutable package? - Is the builder not meant to be used directly? If so, which builder or buffer is to be used to create a `Seq`?

Original source

Related problems