Skip to content

Latest commit

 

History

History
63 lines (42 loc) · 1.99 KB

never-return-unit.md

File metadata and controls

63 lines (42 loc) · 1.99 KB

Never return Unit

When a function returns nothing, returns a Done object instead of Unit.

The Done object does not exist in the Scala standard library but you can create it easily:

sealed abstract class Done

case object Done extends Done

Why doing that?

When returning Unit, the Scala compiler just ignore the returned value. For example, this code returns the last statement which is an Int:

def parse(s: String): Int = s.toInt

but if the return type is set to Unit, the last statement (Int) is ignored, you don't need to provide a Unit to return Unit:

def parse(s: String): Unit = s.toInt

This behavior can be problematic when this is not intended, a classical example is:

import scala.util.Try
def parse(s1: String, s2: String): Try[Unit] =
  Try(s1.toInt).map(_ => Try(s2.toInt))

We may expect to get a Failure if one of the .toInt fails but due to the .map (instead of .flatMap) the real return type is Try[Try[Int]] and the second Try is just hidden.

Returning Done will help as the code will not compile with a .map instead of the .flatMap:

import scala.util.Try
sealed abstract class Done
case object Done extends Done

def parse(s1: String, s2: String): Try[Done] =
  Try(s1.toInt).flatMap(_ => Try { s2.toInt; Done })

This is because Try[Try[Unit]] is a valid Try[Unit] but a Try[Try[Done]] is NOT a valid Try[Done]

To have this compiler help, you should return Done at the end of your computation, inside the second Try and not do a .map(_ => Done) at the end to comply with the requested return type.

Here is a BAD example of using Done:

import scala.util.Try
sealed abstract class Done
case object Done extends Done

def parse(s1: String, s2: String): Try[Done] =
  Try(s1.toInt).map(_ => Try(s2.toInt)).map(res => Done)

As you can see here, res can be Int or Try[Int] (depending on .flatMap or .map), it does not matter and is not caught by the compiler :(