What's the difference between Unit and Nothing?

Both types Unit and Nothing indicate a function that does not return anything. What's the difference between them?


Solution 1:

Unit is a type that has exactly one value ‒ see Unit type. On the other hand, Nothing has no possible value - see Bottom type.

A function that doesn't return anything must have the return type Unit. If it were Nothing then the function could not return a result. The only way to exit the function would be by an exception.


Nothing is used in a different way. It is characterized by two properties:

  1. Nothing is a subtype of every other type (including Null).
  2. There exist no instances of this type.

When is this useful? Consider None:

object None extends Option[Nothing]

Because Option is covariant in its type parameter and Nothing is a subtype of everything, Option[Nothing] is a subtype of Option[A] for every type A. So, we can make one object None which is a subtype of Option[A] for every A. This is reasonable, since Nothing cannot be instantiated so Option[Nothing] will always be without a value. Similarly

object Nil extends List[Nothing]

Unit corresponds to logical true and Nothing corresponds to logical false under the Curry-Howard isomorphism, where we view types as propositions and functions as proofs, .

Solution 2:

Unit means that (a) function has side effects like input and output, (b) these side effects are the main goal of the function. Of course, a function can have side effects even if its type is different from Unit.

Nothing is a special type in Scala, because (a) it has no values (Unit has exactly one value - ()), so you cannot return a value of type Nothing, and (b) it is a subtype of every other type. That means that if something has the type Nothing, it can be used instead of any other type (via subtyping), but it won't produce any result. This is useful for dealing with exceptions - the throw expression has a type of Nothing, so it can be used everywhere in a program.

Simply, Nothing means that there was an error or termination of a program and nothing was returned, while Unit means there were side effects, but execution ended normally with no result.

Programming in Scala has a nice explanation of that.

Solution 3:

To add one aspect to Petr's reply: Nothing plays an important role in the type hierarchy. It is a bottom type. That means that it is a subtype of every other type, which is like the opposite of Any, which is a supertype of everything. You can find a nice explanation here.

Solution 4:

Unit

Unit is same as void of Java. void in java is a keyword but Unit is an Object in Kotlin.

Now if a function returns Unit in Kotlin, it means that it doesn't return anything meaningful, that function just executes a bunch of code and gives back the execution flow.

Nothing

Nothing is a different kind altogether. You can't relate it with anything in Java. There is nothing as such as Nothing in java.

Nothing means the end of execution. If a function returns Nothing, means literally nothing it returns. Not even the execution flow.

Nothing is like a black hole, anything that goes in doesn't come out, Not even the light (light is "execution flow" here). In the case of Unit, least light comes out.

So, if a function returns Nothing, the flow of code ends there and anything written after that is Unreachable.

Now see the code below,

fun main() {
    unitFun()
    println("after unit")
    nothingFun()
    println("after nothing")   //you get warning here saying "unreachable code"
}

fun nothingFun(): Nothing {
    println("inside nothing")
    throw Exception()
}

fun unitFun(): Unit {
    println("inside unit")
}

Output will be

inside unit
after unit
inside nothing
Exception in thread "main" java.lang.Exception

NOTE: you get warning as soon as you write

println("after nothing")     UnReachable Code

And you know the reason, it's because nothingFun doesn't even send back the execution flow.

One more thing to complete this here is, any function that returns Nothing has to throw an exception of any kind.

REASON: If you write some general statement (and not throw an exception) then the function will match the return type and we don't have anything that returns Nothing, means we don't have anything that sucks the execution flow and never returns it back. Everything returns something, even Unit is something.

Now, one can say that Nothing is a class so we can make object of it and return that itself. Nohhhhhhh? A big nohhhh?

Nothing class has one constructor but it is private, so you can't even make an object of it.

Last Bit

Behind the scene, Unit is converted into void(small v) in the decompiled byte code while Nothing is converted into Void(capital V).

see the below code,

var user = null               //First
var user : User? =null        //Second

Here, the Second statement shows, user of Nullable-User type. What is the type of user of the first statement?

any guess?

It's Nullable-Nothing type.

try to see the first statement as

var user : Nothing? = null

Now what's happening under the hood,

Void user = (Void)null;              //First
User user = (User)null;        //Second