Aladdin - Scala Bugtracking
[#1221] project: api priority: low category: bug
submitter assigned to status date submitted
Sean Martin open 2007-07-18 08:55:45.0
subject overloading weirdness: Iterable.++ vs. Buffer.++
code
Check out Iterable.++[B >: A](iter : Iterable[B]) : Iterable[B] and Buffer.++(iter : Iterable[A]) : Buffer[A]

Code:

val x : RandomAccessSeq[Char] = "hello";
val y : String = "world";
val z = new StringBuilder
z ++ (if (true) x else y) // rejected for overloading ambiguity)
z ++ (1 :: Nil) // compiles ok
what happened
Compiler will report nameclashes if both methods are overridden in the same class. Compiler will also puke on ov\
erloading resolution in certain cases (mainly with RichStringBuilder). 

In the code above, the compiler will report ambiguity because implicit coercion doesn't work very well in the pr\
esence of overloading. In this case, it won't apply the implicit coercion to y. 
what expected ++ shouldn't be overloaded in Buffer (and other mutable collections) with a different signature. Actually, I'm surprised the compiler even allows this: it seems to me that it should report a nameclash in Buffer because a new ++ method is defined with a conflicting signature. One of the ++ methods has to be renamed. I don't even think we can deprecate first as this is pretty broken.
[back to overview]
Changes of this bug report
Sean  edited on  2007-07-18 09:32:53.0
Actually, the trick is that each ++ should have a different return type, and the Scala compiler won't report a nameclash. This is sort of a hack, because ideally we'd want both ++ methods in Buffer return Buffers. The fact that RichStringBuilder has two ++ methods makes it very fragile with respect to type inference. Added some example code to demonstrate why overloading of ++ creates problems. I think we could deprecate if we wanted to. I now remember why Martin did this: ++ can be seen as a way of going from mutable to immutable collection and its useful. However, overloading in Scala is very fragile, i.e., type inference gives up more quickly in the presence of overloaded methods. One possible solution would be to defer adding ++ until mutable (invariant)/immutable (covariant) is fixed. That way, we avoid overloading in mutable collections.