Skip to content

Commit e9c67ef

Browse files
authored
add a subsection explaining the relationship between immutability and variance
1 parent 94c9ac3 commit e9c67ef

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

_tour/variances.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,19 @@ case class Mouse(name: String) extends SmallAnimal
136136

137137
Suppose we're working with functions that accept types of animals, and return the types of food they eat. If we would like a `Cat => SmallAnimal` (because cats eat small animals), but are given a `Animal => Mouse` instead, our program will still work. Intuitively an `Animal => Mouse` will still accept a `Cat` as an argument, because a `Cat` is an `Animal`, and it returns a `Mouse`, which is also a `SmallAnimal`. Since we can safely and invisibly substitute the former with the latter, we can say `Animal => Mouse` is a subtype of `Cat => SmallAnimal`.
138138

139+
### Immutability and Variance
140+
Immutability constitutes an important part of the design decision behind the variance. As previously explained, Scala collections systematically distinguish between [Mutable and Immutable Collections](https://docs.scala-lang.org/overviews/collections-2.13/overview.html). For collections, mutability combined with covariance may break type safety. ```List``` is a covariant collection, while ```Array``` is an invariant collection. ```List``` is a collection in package ```scala.collection.immutable```, therefore it is guaranteed to be immutable for everyone. Whereas, ```Array``` is mutable, that is, you can change, add, or remove elements of an ```Array```. Following initialization wouldn't get compiled since ```Array[Int]``` is not a subtype of ```Array[Any]``` although ```Int``` is a subtype of ```Any```.
141+
```scala mdoc
142+
val arr:Array[Any] = Array[Int](1,2,3)
143+
```
144+
The reason is that if Scala allowed mutable collections to be covariant, then the type error in the following statements wouldn't be catched by the compiler and it would break type safety.
145+
```scala mdoc
146+
val arr:Array[Int] = Array[Int](1,2,3)
147+
val arr2:Array[Any] = arr
148+
arr2(0) = 3.14
149+
```
150+
151+
139152
### Comparison With Other Languages
140153

141154
Variance is supported in different ways by some languages that are similar to Scala. For example, variance annotations in Scala closely resemble those in C#, where the annotations are added when a class abstraction is defined (declaration-site variance). In Java, however, variance annotations are given by clients when a class abstraction is used (use-site variance).

0 commit comments

Comments
 (0)