Mutable vs Immutable Set

I’ve just started learning Scala.
I’m confused about the difference between Mutable and Immutable set.
Below code returns same results:

var jetSet=Set("hello","world")
jetSet+="!"
println(jetSet)

jetSet=Set("new1","new2")
println(jetSet)

import scala.collection.mutable

var mutSet=mutable.Set("hi","Mutable")
mutSet+="Set"
println(mutSet)

mutSet=mutable.Set("new1","new2")
println(mutSet)

Result:

Set(hello, world, !)
Set(new1, new2)
HashSet(Mutable, hi, Set)
HashSet(new2, new1)

Please explain the difference.

If you want to see the difference, try replacing var by val (you should use val in scala unless you want mutability for a specific reason). You have mutable variables, so the two look similar.

regards,
Siddhartha

1 Like

Thanks for your reply Siddhartha.

But if var/val makes the difference, then what’s the point of having mutable and immutable sets?

Hi Pragya, I started writing something up, but I think this link explains it better than I was going to.

1 Like

Normally one uses vals and immutable sets. If one wants mutability, one can either use a var or a mutable set. Using both (double mutability) is error prone (as explained above) and no use.

The reason to have the option of mutable sets, rather than always using vars, is performance. It is easier to add a single element to a huge mutable set rather than (as you would be doing with var) create a new huge immutable set which is the old one with a single new element, and point the var at this.

regards,
Siddhartha

2 Likes

There are two kinds of mutability:

  • Reference mutability: You can make your variable point to a different object but the previous object stays unchanged.
  • Value mutability: You can modify the contents / state of a value and the variable still points to the same object.
Reference mutability Value mutability
val + s.c.i.Set N N
var + s.c.i.Set Y N
val + s.c.m.Set N Y
var + s.c.m.Set Y Y

Usually, you should stay immutable in both, because that makes your code easier to understand and refactor.
Mutability, especially between more global it is, implies that you can no longer focus on some subset of your code but you have to always understand how all the code interacts and mutates the values.
Sometimes, a local mutable reference / mutable datastructure is useful for performance reasons or for making the code easier to read. But, those should be implementation details and then always receive and return immutable values.

BTW, you probably are confused with this: jetSet+="!"
It is expanded like this:

jetSet = jetSet + "!"

So, as you can see it doesn’t mutate the previous set, it creates a new set and then replaces the reference.

4 Likes

Thanks for the explanation Balmung

in addition, “val” get the better performance than “var”. but the difference is quite slight.