Search code examples
scalacollectionsimmutabilityfinal

Both var and val are creating immutable Set, but var is allowing to add a new value whereas val is not


I am from Java background and trying to learn Scala.

There is an example as below in the book "Programming in Scala - Third Edition"

var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"
println(jetSet.contains("Cessna"))

The first line creates an immutable non-final Set:

jetSet: scala.collection.immutable.Set[String] = Set(Boeing, Airbus)

The second line runs with no errors.

Now, when I change the first line from var to val, the second line gives error:

<console>:13: error: value += is not a member of scala.collection.immutable.Set[String]
   jetSet += "Lear"

I am not able to understand the reason behind it. val corresponds to final and var is non-final. I am not assigning the variable to any new Set. In both the cases, the Set is immutable.

How is var or val impacting things here?

Also, when jetSet is immutable in both the cases, why is it allowing to add a new value to the set in the case of var. Does it not violate the immutability principle.

Correct my understanding, please.


Solution

  • Case: 1

    scala> var jetSet = Set("Boeing", "Airbus")
    jetSet: scala.collection.immutable.Set[String] = Set(Boeing, Airbus)
    
    scala> jetSet
    res3: scala.collection.immutable.Set[String] = Set(Boeing, Airbus)
    
    scala> jetSet += "Lear"
    
    scala> jetSet
    res5: scala.collection.immutable.Set[String] = Set(Boeing, Airbus, Lear)
    

    Case: 2

    scala> val jetSet = Set("Boeing", "Airbus")
    jetSet: scala.collection.immutable.Set[String] = Set(Boeing, Airbus)
    
    scala> jetSet += "Lear"
    <console>:13: error: value += is not a member of scala.collection.immutable.Set[String]
           jetSet += "Lear"
                  ^
    

    In case: 1 when var is used. += is understood as follows

    jetSet += "Lear" is nothing but jetSet = jetSet + "Lear"

    + will create a new Set with "Lear" added to it along with others already in jetSet Set.

    Note that here only reference is mutable but set is immutable. + method creates a new set (new reference code will be assigned to mutable variable.)

    case 2: When val is used. Compiler thinks += is method and tries to find if such a method is declared in immutable Set class. So, it gives a compilation error in case of val.

    Immutable Set has no += method declared in it. While mutable Set as += method declared.