This is an excerpt from the Scala Cookbook (partially re-worded for the internet). This is Recipe 10.6, “Understanding Mutable Variables with Immutable Collections.”
Problem
You may have seen that mixing a mutable variable (var) with an immutable collection causes surprising behavior. For instance, when you create an immutable Vector as a var, it appears you can somehow add new elements to it:
scala> var sisters = Vector("Melinda")
sisters: collection.immutable.Vector[String] = Vector(Melinda)
scala> sisters = sisters :+ "Melissa"
sisters: collection.immutable.Vector[String] = Vector(Melinda, Melissa)
scala> sisters = sisters :+ "Marisa"
sisters: collection.immutable.Vector[String] = Vector(Melinda, Melissa, Marisa)
scala> sisters.foreach(println)
Melinda
Melissa
Marisa
How can this be?
Solution
Though it looks like you’re mutating an immutable collection, what’s really happening is that the sisters variable points to a new collection each time you use the :+ method.
The sisters variable is mutable — like a non-final field in Java — so it’s actually being reassigned to a new collection during each step. The end result is similar to these lines of code:
var sisters = Vector("Melinda")
sisters = Vector("Melinda", "Melissa")
sisters = Vector("Melinda", "Melissa", "Marisa")
In the second and third lines of code, the sisters reference has been changed to point to a new collection.
You can demonstrate that the Vector itself is immutable. Attempting to mutate one of its elements — which doesn’t involve reassigning the variable — results in an error:
scala> sisters(0) = "Molly"
<console>:12: error: value update is not a member of
scala.collection.immutable.Vector[String]
              sisters(0) = "Molly"
              ^
Summary
When you first start working with Scala, the behavior of a mutable variable with an immutable collection can be surprising. To be clear about variables and values:
- A mutable variable (var) can be reassigned to point at new data.
- An immutable variable (val) is like afinalvariable in Java; it can never be reassigned.
To be clear about collections:
- The elements in a mutable collection (like ArrayBuffer) can be changed.
- The elements in most immutable collections (like VectorandList) cannot be changed.
The
Arraydoes not obey the second statement about collections, so I used the word “most” in that sentence rather than “all.” Because the ScalaArrayis backed by a Javaarray, the elements in anArraycan be changed after theArrayis first created. You can’t make theArraylonger or shorter, but you can re-assign an element, like this:elements(0) = "foo"
| this post is sponsored by my books: | |||
|   #1 New Release |   FP Best Seller |   Learn Scala 3 |   Learn FP Fast | 
See Also
- Recipe 20.2, “Prefer Immutable Objects”, discusses the use of mutable variables with immutable collections, and its opposite, using immutable variables with mutable collections as a “best practice.”






