1

I thought that Scala classifies statements as type Unit. But when I run the following code:

object HelloWorld {
  var ball = new Ball

  def main(args: Array[String]): Unit = {
    println((ball.color = "green").getClass)
  }
}

class Ball {
  var color: String = "blue"
}

The output is

void

I have learned that void is only used in Scala for compatibility with Java. So why is void here used as type of this statement and not Unit?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Aaron
  • 124
  • 11
  • Just to clarify a bit: in Scala, `ball.color = "green"` is an expression. It can be used as a statement, but in `(ball.color = "green").getClass` it isn't; only the entire `println(...)` is a statement here. If you try it with a statement which can't be an expession, e.g. `(var ball = new Ball).getClass()`, you'll see that you can't call a method on a statement and they don't have types. – Alexey Romanov Jun 03 '20 at 16:40
  • @AlexeyRomanov By the way `{var ball = new Ball}.getClass()` will be `void`. But `{var ball = new Ball}` is actually `{var ball = new Ball; ()}`. – Dmytro Mitin Jun 03 '20 at 16:46

2 Answers2

4

The compile-time type of assignment expression is Unit

val x: Unit = (ball.color = "green")

and the string representation of the corresponding runtime class is void

().getClass
// res1: Class[Unit] = void

I guess assignment is considered a side-effect and side-effects are expressed with Unit type.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
4

getClass comes from Java. If you jump to the definition of getClass in your IDE you'll get to java.lang.Object#getClass

public final native Class<?> getClass();

If you use Scala reflection you'll see that the type is Unit

//libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
import scala.reflect.runtime.universe._
def getType[T: TypeTag](t: T): Type = typeOf[T]

getType(ball.color = "green") // Unit

Class and type of a value are different concepts.

https://typelevel.org/blog/2017/02/13/more-types-than-classes.html

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66