A colleague approached me a while ago and asked me a question about **Kotlin**. What was this “Nothing type”, and what was it used for? I did not really have a good answer for him at the time. Since then, I’ve found my answer.

### Nothing Type is the Bottom Type

In mathematics, bottom (often denoted as _|_) represents the absolute minimum value something can hold.

Nothing type has no instances. You can use Nothing to represent “a value that never exists”: for example, if a function has the return type of Nothing, it means that it never returns (always throws an exception).

**Previously shared Kotlin post:**

- Top 12 Advanced Kotlin Tips For Pro Developers
- Kotlin Parcelize – Developer need to know
- Create Firefox Extension Using KotlinJS

When we’re talking about types, we can think of `Nothing`

as being the absolute bottom (leaf) object of any type hierarchy.

What we can see in this diagram (figure 1) is that `Nothing`

is the opposite of `Any`

. While every object you will work with in Kotlin implicitly extends `Any`

, so to does `Nothing`

implicity extend any object that exists. This makes `Nothing`

the ‘dual’ or opposite of `Any`

.

So, why is this useful?

### Covariant Types (an Example)

We can use `Nothing`

along with covariant (producer) types to help make our code more concise and expressive. The following is an example of the `Nothing`

type in action. It is of an `Either`

monad, which can exclusively represent one of two types (`L`

or `R`

), and provides methods for mapping over the values it wraps, including a right-biased `map`

and `flatMap`

(by convention) and a very useful `either`

method.

// Composes 2 functions fun <A, B, C> ((A) -> B).c(f: (B) -> C): (A) -> C = { f(this(it)) } // A simple Either monad sealed class Either<out L, out R> { data class Left<out L>(val a: L) : Either<L, Nothing>() data class Right<out R>(val b: R) : Either<Nothing, R>() val isRight: Boolean get() = this is Right<R> val isLeft: Boolean get() = this is Left<L> } fun <L> left(a: L) = Either.Left(a) fun <R> right(b: R) = Either.Right(b) fun <T, L, R> Either<L, R>.flatMap(fn: (R) -> Either<L, T>): Either<L, T> = when (this) { is Either.Left -> Either.Left(a) is Either.Right -> fn(b) } fun <T, L, R> Either<L, R>.map(fn: (R) -> (T)): Either<L, T> = this.flatMap(fn.c(::right)) fun <T, L, R> Either<L, R>.either(fnL: (L) -> T, fnR: (R) -> T): T = when (this) { is Either.Left -> fnL(a) is Either.Right -> fnR(b) }

Covariance (marking our parameters as `out`

) allows us to utilize nothing in the `R`

and `L`

positions of the `Left`

and `Right`

declarations of the `Either`

monad implemented here (respectively). Our functions all typecheck and are happy. For example, something like:

val e = right(42).flatMap(r -> left(Exception())

Will happily type-check and compile. We can even rigidly express the type of `e`

and it’s still happy as can be, all thanks to `Nothing`

and covariance:

val e: Either<Int, Exception> = right(42) .flatMap { left(Exception() }

You might have noticed that extension methods are being used here for `map`

, `flatMap`

, and so on. This is due to the Covariant typing mentioned above, which produces type-check errors when trying to pass a lambda utilizing the generic types. Extension methods are a quick and easy way around this issue.

### So what did we actually get?

What we end up with is a better, more concise way to express our types. Nothing almost acts like a type hole, similar to utilizing `_`

in lambda arguments. We can use it in places where we really just don’t care about the type of something. In our case, if we’ve got a `Right`

, we don’t really need to know anything about the error, because it doesn’t exist. On the other hand, if we have a `Left`

, knowledge of the error is necessary, but not so much for the normal value.

Hopefully this sheds some light on why `Nothing`

exists and how it can be leveraged.

## Share your thoughts