user5607337
user5607337

Reputation:

Unit vs Nothing in Scala

I'd like to clarify some details about Unit and Nothing.

For example:

def unit(companyId: Int): Unit = {}

def Nothing(companyId: Int): scala.Nothing = {}

According to the docs, Unit in Scala is very similar to void in Java. But

test("test Unit and Nothing") {
  println(unit(1))
}

Why does Scala has overflow type Unit which return Nothing? Why Scala cannot useNothing instead of Unit?

Upvotes: 3

Views: 2258

Answers (1)

Chris Martin
Chris Martin

Reputation: 30736

Unit has cardinality 1. Nothing has cardinality 0.

Your second example

def Nothing(companyId: Int): scala.Nothing = {}

doesn't compile. It's impossible to return a Nothing, because Nothing has no inhabitants. Therefore a function that returns Nothing cannot return normally; it can only throw an exception.

def Nothing(companyId: Int): scala.Nothing = { throw new Exception(); }

Java's Void is comparable to Unit in that Void also has cardinality 1; its sole inhabitant is null. There is no type with cardinality 0 in Java (nor is it possible to define such a type), so Java does not have a type that is comparable to Nothing. It is, of course, possible to write a Java method that always throws an exception, but it is not possible for the return type to express that.


Consider what happens when you use each of these in collections. For example, a List[Unit] can contain any number of Unit values:

List()           : List[Unit]
List((), (), ()) : List[Unit]

whereas a List[Nothing] is necessarily empty, because there is nothing you can put into it.

List()           : List[Nothing]

The other important thing to note about Nothing is that it's a subtype of every other type. This makes sense, because it has no inhabitants; therefore every proposition (propositions are closely related to types) about Nothing instances holds vacuously. For an example of why this is useful, again consider lists:

List.empty[Nothing] : List[String]

Here we ascribe a List[Nothing] to the type List[String], which we can do because List's type parameter is covariant and Nothing is a subtype of String. Note that we couldn't do that with a List[Unit], because Unit is not a subtype of String.

Upvotes: 13

Related Questions