Re: Possible inconsistent error for "+=" shorthand while using immutable set

som-snytt <[email protected]> Mon, 28 Mar 2016 10:04:14 -0700 (PDT)
Newsgroups gmane.comp.lang.scala
Message-ID <[email protected]>
The spec quote was taken backward: if x += y doesn't typecheck, then it 
tries x = x + y (if that type checks). The quoted part also wrongly implies 
that rewriting happens only when using infix syntax.

I agree that the error messages could include what was tried (and maybe how 
to fix it).

scala> class C
defined class C

scala> var c = new C
c: C = C@41a4555e

scala> c += 1
<console>:14: error: type mismatch;
 found   : Int(1)
 required: String
       c += 1
            ^

scala> c.+=(1)
<console>:14: error: type mismatch;
 found   : Int(1)
 required: String
       c.+=(1)
            ^

scala> c.+=("1")
<console>:14: error: type mismatch;
 found   : String
 required: C
       c.+=("1")
           ^

scala> :replay -Yno-predef
Replaying: class C
defined class C

Replaying: var c = new C
c: C = C@3576ddc2


scala> c += 1
<console>:14: error: value + is not a member of C
       c += 1
         ^

scala> c.+=(1)
<console>:14: error: value + is not a member of C
       c.+=(1)
         ^

scala> val c = new C
c: C = C@495ee280

scala> c.+=(1)
<console>:14: error: value += is not a member of C
       c.+=(1)
         ^


On Sunday, March 27, 2016 at 6:24:55 PM UTC-7, Christopher Lee wrote:
>
> Hey Andrew,
>
> Thanks for the clear explanation! The behavior makes sense to me now :)
>
> This might be crazy, but I wonder if it makes sense for immutable set to 
> have a "+=" member (along with any other assignment operator) that throws a 
> reassignment error.
>
> Thanks again,
> Chris
>
> On Sunday, March 27, 2016 at 2:03:14 PM UTC-4, Andrew Phillips wrote:
>>
>> Hi Chris
>>
>> The behaviour you're seeing is indeed consistent with the language spec, 
>> although I can imagine that it appears odd at first sight. In short, the 
>> rewriting of a += b to a = a + b can only take place if a is something 
>> "that can be assigned". Since that's not true for a val, the rewriting does 
>> *not* take place, and so the compiler is forced to look for a member 
>> "+=" on a instead. Since a in your example is an immutable set, it can't 
>> find one (mutable sets *do* have a "+=" method [1]).
>>
>> Section 6.12.4 of the language spec [2] describes this in detail; here an 
>> excerpt:
>>
>>
>> Let’s consider an assignment operator such as += in an infix operation l 
>> += r ,
>> where l, r are expressions. This operation can be re-interpreted as an 
>> operation
>> which corresponds to the assignment
>>
>> l = l + r
>>
>> [...] if the following two conditions are fulfilled.
>>
>> [...]
>>
>> 2. The assignment l = l + r is type-correct. In particular this implies 
>> that l
>> refers to a variable or object that can be assigned to, and that is 
>> convertible
>> to a value with a member named +.
>>
>>
>> Hope that helps!
>>
>> ap
>>
>> [1] 
>> http://www.scala-lang.org/api/current/index.html#scala.collection.mutable.Set@+=(elem:A):SetLike.this.type
>> [2] 
>> http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#assignment-operators
>>
>> On Sunday, 27 March 2016 18:11:00 UTC+1, Christopher Lee wrote:
>>>
>>> Hello,
>>>
>>> I'm just starting to learn Scala, and I came across the following 
>>> example in the "Programming in Scala" book.
>>>
>>> var jetSet = Set("Boeing", "Airbus")
>>> jetSet += "Lear"
>>> println(jetSet.contains("Cessna"))
>>>
>>> One of the lesson points is that the default Set is immutable. So, I 
>>> wanted to test that line 2 in the above actually reassigns a new immutable 
>>> set with the element added to the jetSet variable.
>>>
>>> I then *changed the var to a val* and expected to see a reassignment 
>>> error. Instead I got the below error.
>>>
>>> immutableSet.scala:2: error: value += is not a member of scala.
>>> collection.immutable.Set[String]
>>> jetSet += "Lear"
>>>        ^
>>>
>>> While the error message is true, it's strange that the compiler didn't 
>>> complain about "+=" before. "+=" is shorthand for `jetSet = jetSet + 
>>> "Lear"`, so I would expect to see a reassignment error.
>>>
>>> E.g. If I were to run the program with the long form, I get the expected 
>>> error message.
>>>
>>> val jetSet = Set("Boeing", "Airbus")
>>> jetSet = jetSet + "Lear"
>>> println(jetSet.contains("Cessna"))
>>>
>>> immutableSet.scala:2: error: reassignment to val
>>> jetSet = jetSet + "Lear"
>>>        ^
>>>
>>> Am I missing something (very likely since I'm a newb) or does this seem 
>>> inconsistent?
>>>
>>> Thanks for reading!
>>> Chris
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.