Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading on return type?

Tags:

scala

scala> val shares = Map("Apple" -> 23, "MicroSoft" -> 50, "IBM" -> 17)
shares: scala.collection.immutable.Map[java.lang.String,Int] 
      = Map(Apple -> 23, MicroSoft -> 50, IBM -> 17)

scala> val shareholders = shares map {_._1}                           
shareholders: scala.collection.immutable.Iterable[java.lang.String] 
            = List(Apple, MicroSoft, IBM)

scala> val newShares = shares map {case(k, v) => (k, 1.5 * v)}     
newShares: scala.collection.immutable.Map[java.lang.String,Double] 
         = Map(Apple -> 34.5, MicroSoft -> 75.0, IBM -> 25.5)

From this example it seems like the map method is overloaded on return type. Overloading on return type is not possible right? Would somebody please explain what's going on here?

like image 400
Green Hyena Avatar asked May 02 '10 08:05

Green Hyena


3 Answers

map isn't overloaded on return type. Instead, there is one method with an abstract return type.

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

In the bytecode, this is erased to Object:

public abstract java.lang.Object map(scala.Function1, scala.collection.generic.CanBuildFrom);

The pattern is described best in the paper Fighting Bit Rot with Types

like image 72
retronym Avatar answered Nov 10 '22 21:11

retronym


This isn't what's going on in this case, but actually yes, overloading on return type is supported by JVM. This is exposed in Scala for methods which have different generic argument types which erase to the same type. The example given at the link is

object Overload{
  def foo(xs : String*) = "foo"; // after erasure is foo:(Seq)String
  def foo(xs : Int*) = 3;        // after erasure is foo:(Seq)Int
}
like image 6
Alexey Romanov Avatar answered Nov 10 '22 21:11

Alexey Romanov


You might want to look at this question about the signature of map which has a parametric return type That. Martin Odersky's answer explains how (and why) different types may be returned.

Note that the return type is not bound in any way to Traversable, or even the parametrized type of the target. For example:

IndexedSeq[Char].map --> String

As can be seen by looking at StringOps

like image 4
oxbow_lakes Avatar answered Nov 10 '22 20:11

oxbow_lakes