What is Scala’s Nothing type for?

jooohn
4 min readJun 2, 2018

--

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, Nothing is a subtype of all types. That means, Nothing is a subtype of Int and also is a subtype of String and List[User].

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 Int, String, and List[User]. 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 Nothing type for?

… In fact, Nothing 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 Int or throws an exception.

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

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

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! throw new Exception(s"$num is not 1")'s type can be Int. In the same way, it should be legitimate to use throw 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 throw expressions as Nothing type. Do you remember? Nothing is a subtype of all types so it can be an Int, String, and A. throw doesn’t return an concrete value, but it should be any type. Here, Nothing seems to be a perfect choice. Thanks to it, Scala type checker can treat throw like any other expression.

Stub

Another usage of Nothing 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 throw, but just a method defined at Predef as Nothing type.

def ??? : Nothing = throw new NotImplementedError

Thanks to its flexibility of Nothing, 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 Nil or None. Higher kinded type like Option andList MAY contain A values in it. At the same time, they MAY NOT contain a value, and such empty values are declared as Nil or None in Scala.

You might have used None as type Some[Int] or you might have used Nil as List[User]. Again, Nothing 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, Nothing is used as type parameter +A of Option[+A]. This + variance is important to let Option[B] replace Option[A] when B is a subtype of A. As I mentioned many times in this post, Nothing is a subtype of all types. Therefore Option[Nothing] is a subtype of Option[Int] and Option[User] and all possibleOption[A] types. There is no value of Nothing, but it’s not a problem because both Nil and None are empty.

Conclusion

At first glance, Nothing 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 Nothing in daily programming, but definitely it makes Scala more elegant.

--

--