iman
iman

Reputation: 339

Syntax of += for immutable Set

For a mutable Set += method (operator) will have side effect and changes the set itself. As an example:

val mySet = scala.collection.mutable.Set(1, 2, 3)
mySet += 4

In the above example a new instance of Set is not created, but the existing one mutated. += is an actual method of mutable Set, so we can write the last line as:

mySet.+=(4)

However for immutable Set when we use += a new Set instance is created:

var myOtherSet = Set(1, 2, 3)
myOtherSet += 4

Why += is not an actual method of immutable Set even though we use it like a method that is applied to Set?

Upvotes: 1

Views: 121

Answers (3)

Jörg W Mittag
Jörg W Mittag

Reputation: 369458

My question is that based on the book I am reading why += is not an actual method of immutable Set even though we use it as a method that is applied to Set?

There is no += method for immutable Sets (or any other immutable collection).

The rule is that an operator assignment expression of the form a ω= b is first interpreted as a.ω=(b) if that type-checks, but if it doesn't type-check, then it alternatively gets interpreted as a = a ω b (provided that type-checks).

So, the reason myOtherSet += 4 works, is that there is a + method defined, myOtherSet is a var, and the expression gets interpreted as myOtherSet = myOtherSet + 4.

Upvotes: 4

uberwach
uberwach

Reputation: 1109

If you have a var, then += stands for an assignment and +, i.e. x += y gets translated to x = x + y. In this case += is not a method, but syntactic sugar. Except, if there is an explicit += method defined.

This does not only hold for Set, but for all types. Consider the following example:

case class NewInt(var x : Int) {  
  def +(y: Int) = { println("+"); NewInt(x + y) }
}

var n = NewInt(3)
n += 3 // outputs +, n == NewInt(6) now
val n2 = NewInt(3)
n2 += 3 // error

case class SuperInt(var x : Int) {
  def +=(y: Int) = { println("+="); x = x + y }
  def +(y: Int) = { println("+"); SuperInt(x + y) }
}

var n3 = SuperInt(3)
n3 += 3 // outputs +=, n3 == SuperInt(6)
val n4 = SuperInt(3)
n4 += 3 // outputs +=, n4 == SuperInt(6)

Upvotes: 2

sepp2k
sepp2k

Reputation: 370122

why can't we call it an actual method of immutable Set?

Most obviously because no method += is defined in the immutable Set class or any of its super classes (nor any class for which an implicit conversion exists).

It also acts differently in some respects than methods do:

  • You can only use += if myOtherSet is a var instead of a val. You also can't use it on anything other than a variable. Methods can be used on any type of expression that evaluated to the method's class regardless of whether it's a val, a var or some other type of expression.
  • += on a var that contains an immutable object will make the variable point to a different object (because obviously you can't change the object itself). So after you do myOtherSet += 4, the identity of myOtherSet changes. A method can never do that.

Upvotes: 1

Related Questions