2

Sorry guys, I recently saw an example in "Programming in Scala", 2nd Edition on page 685, which seemed strange to me:

var hashSet: Set[C] = new collection.immutable.HashSet hashSet += elem1 

How is it possible to add something an immutable collection? I tried on REPL and it worked ok!

> scala Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11). Type in expressions to have them evaluated. Type :help for more information. scala> var s : Set[Int] = collection.immutable.HashSet() s: Set[Int] = Set() scala> s += 1324 scala> println(s) Set(1324) 

The stranger fact is that += operator is not defined in immutable.HashSet api page. Could anybody please help me understand what's going on?

Thanks.

1
  • Cannot speak to how += is handled syntax-wise, but adding to an immutable HashSet is just like appending to an immutable String: You get a new instance with the modified contents. Commented Apr 27, 2015 at 5:00

3 Answers 3

5

You are not adding to the HashSet. You are assigning to hashSet, which is perfectly fine, since hashSet is a var, not a val.

Section 6.12.4 Assignment Operators of the Scala Language Specification (SLS) explains how such compound assignment operators are desugared:

l ω= r 

(where ω is any sequence of operator characters other than <, >, ! and doesn't start with =) gets desugared to

l.ω=(r) 

iff l has or is implicitly convertible to an object that has a member named ω=.

Otherwise, it gets desugared to

l = l.ω(r) 

(except l is guaranteed to be only evaluated once), if that typechecks.

This allows something like += to work like it does in other languages but still be overridden to do something different.

Sign up to request clarification or add additional context in comments.

Comments

3

Observe this:

scala> var hashSet: Set[Int] = new collection.immutable.HashSet hashSet: Set[Int] = Set() scala> val set2 = hashSet + 1234 set2: scala.collection.immutable.Set[Int] = Set(1234) scala> set2 res20: scala.collection.immutable.Set[Int] = Set(1234) scala> hashSet res21: Set[Int] = Set() 

So nothing gets added to the immutable hashSet. hashSet is the same as it was when constructed. + returns a new set altogether and the original set is unchanged.

When you do hashSet += 1234, it is a scala shorthand for (note no method += exists in HashSet):

val temp = hashSet + 1234 hashSet = temp 

+= will work for any class which follows this protocol. In short when you do a += 12. a must have a method + which returns the same type as a's and a should be assignable (i.e. a var. It does not work for val. Try this: val i = 23; i+=1).

Comments

2

Short answer

You have a var so you can reassign to it. So += in this case will be translated to

hashSet = hashSet + elem 

just like other types, as long as + is defined on them

var i = 0 i += 1 i = i + 1 

Details

immutable.HashSeth has + method which

Creates a new set with an additional element, unless the element is already present.

according to docs.

There is no += method defined in this class, so += will be a synthetic method given to you by compiler which acts as an operator simply calling the + method on the left operand by passing the right operand and assigning the result back to the left operand.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.