What is Scala’s Nothing type for?

What is “Nothing”?

Nothing is a subtype of all types, also called the bottom type.
https://docs.scala-lang.org/tour/unified-types.html

As the Scala official doc says, is a subtype of all types. That means, is a subtype of and also is a subtype of and .

When I happened to see the definition at the first time, I was confused, and I read that definition out again and again, but I couldn’t figure out what does it mean. A subtype of , , and . Is there such a magical value?

Of course, Scala doc answers to this quite natural question.

There is no value that has type Nothing
https://docs.scala-lang.org/tour/unified-types.html

“There is no value that has type Nothing”. Again, I read it out again and again, but it definitely says there is no value like that. It’s weird. If there’s no such value, what is type for?

… In fact, is definitely an important part of the Scala’s type system.

Type for expression which doesn’t return a value

Assume you have a method that returns or throws an exception.

def oneOrThrow(num: Int): Int =
if (num == 1) num
else throw new Exception(s"$num is not 1")

The expression should be an . In the positive case, is apparently , but how about case? If you add type annotation to the both cases, that should look like this to return :

def oneOrThrow(num: Int): Int =
if (num == 1) (num: Int)
else (throw new Exception(s"$num is not 1")): Int

Actually we can compile this without an error! 's type can be . In the same way, it should be legitimate to use where any possible type is required.

// These snipets can be compiled without an error.
val int: Int = throw new Exception("fake Int")
val string: String = throw new Exception("fake String")
val maybeUser: Option[User] = throw new Exception("fake User")
def equalsOrFail[A](l: A, r: A): A =
if (l == r) l
else throw new Exception(s"$l is not $r")

Here, Scala compiler treats expressions as type. Do you remember? is a subtype of all types so it can be an , , and . doesn’t return an concrete value, but it should be any type. Here, seems to be a perfect choice. Thanks to it, Scala type checker can treat like any other expression.

Stub

Another usage of is . is useful when developing an outline of features without considering their implementation detail.

// TODO: Implement them later.
def resolveAuthor(authorId: AuthorId): Future[User] = ???
def storeAuthor(author: Author): Future[Unit] = ???
def updateAuthorName(authorId: AuthorId, name: AuthorName): Future[Unit] =
for {
author <- resolveAuthor(authorId)
_ <- storeAuthor(author.updateName(name))
} yield ()

Quite useful. Anyway, an interesting and beautiful fact about is that it’s not a special syntax like , but just a method defined at as type.

def ??? : Nothing = throw new NotImplementedError

Thanks to its flexibility of , we can use as a stub of any required type.

Empty object for higher kinded types

The last example I introduce is for empty object like or . Higher kinded type like and MAY contain values in it. At the same time, they MAY NOT contain a value, and such empty values are declared as or in Scala.

You might have used as type or you might have used as . Again, helps this flexibility.

sealed abstract class Option[+A]final case class Some[+A](value: A) extends Option[A] { ... }case object None extends Option[Nothing] { ... }

Here, is used as type parameter of . This variance is important to let replace when is a subtype of . As I mentioned many times in this post, is a subtype of all types. Therefore is a subtype of and and all possible types. There is no value of , but it’s not a problem because both and are empty.

Conclusion

At first glance, is weird and useless. However, its replaceability is quite powerful in Scala’s type system. I introduced some usages which I think are beautiful. You might not aware of in daily programming, but definitely it makes Scala more elegant.