What's the difference between (-1).toShort and -1.toShort in Scala

Given the following scala code:

val mapAll= Map("A"-> 1.toShort, "B"-> 2.toShort)
val map1 = Map("A"-> 1.toShort)
val map2 = mapAll.map(x => (x._2, map1.getOrElse(x._1, -1.toShort)))

In this case,the type of map2 shown in IDEA is Map[Short, Int].
What I need is Map[Short, Short]

However, if put the -1 into "()" like this"

val map2 = mapAll.map(x => (x._2, map1.getOrElse(x._1, (-1).toShort)))

It's just fine. the type of map2 shown in IDEA is Map[Short, Short]

So, What's the difference between "(-1).toShort" and "-1.toShort"

2 answers

  • answered 2018-07-12 06:52 Yuval Itzchakov

    There's no difference. You're probably tricked by IntelliJ's bad type inference in this case. You can see this when compiling scalac with the -Xprint:typer flag:

    val map2: scala.collection.immutable.Map[Short,Short] = 
      mapAll.map[(Short, Short), scala.collection.immutable.Map[Short,Short]](
        ((x: (String, Short)) => scala.Tuple2.apply[Short, Short](
           x._2, map1.getOrElse[Short](x._1, -1.toShort))))
          (immutable.this.Map.canBuildFrom[Short, Short]);
    

    We can also verify this by simplifying the example:

    val shortOne = -1.toShort
    val shortTwo = (-1).toShort
    

    And compiling with -Xprint:jvm to see the final emitted step:

    val shortOne: Short = -1.toShort();
    val shortTwo: Short = -1.toShort();
    

    You can see both are identical.

  • answered 2018-07-12 13:58 C4stor

    On Short, - is defined like this : def unary_- : Int

    Happens, -1.toShort is understood as -(1.toShort) by IDEA, of type Int, and (-1).toShort is correctly typed Short, since this is the type of toShort which is now "called" after the - instead of before.