Resist the side effect: Effect Types -1-

Turning effect into data

In the previous articles we saw why avoiding side effect is an important part in achieving a pure function with all the benefits that are related to it, today we are going to see how to manage those side effects.

Usually developing a piece of software requires us to encode business logic in the code, that the first scope any dev is facing will be facing , but soon enough we are facing another scope specific to the code :
-Exception handling
-Concurrency
-Logging
Although addressing the first scope will result in a software that meets the business requirement, we need to address the 2nd scope to get a reliable code.

An instinctive solution is just to handle them locally, lets say you have a function where a division by Zero might happen, handling the exception inside the function might be the straightforward way to do it: throwing an exception, doing so increase the mental load as we need to remember that a this specific function might throw an exception.
Lucky we are, Scala happens to offer infrastructure to cope with side effects called effect type, we are going to view some of them here:

Effect type

Future: as discussed previously asynchronous actions are a side effect since we don’t have control on when these action are gonna be completed
Scala offers us a Future[A] as a type to cope with this kind of situation, it represents a computation that runs in a separate thread and use the callback.
NB: for the future to work it needs an execution context to manage the thread pool, we usually make use of the default Scala.
NB2: Future might not be the best container as it is eager, more on this in the next posts…

Either: Let’s first talk about Try :
The Try type represents a computation that may either result in an exception, or return a successfully computed value. scala-lang reference
lets see an example

def functionalDivision(n1: Double, n2: Double): Try[Double] = 
  if(n2 == 0) Failure(new RuntimeException("Division by zero!"))
  else Success(n1/n2)

Try is used to pass both the value in case of success and the exception if failure.
What we would like to pass is not the exception but the reason for the exception , Try needs a subclass of throwable, thats where Either gets in :

def functionalDivision(n1: Double, n2: Double): Either[String, Double] = 
  if(n2 == 0) Left("Division by zero!")
  else Right(n1/n2)
println(division(1, 0)) //Left("Division by zero!")
println(division(0, 1)) //Right(1.0)

Either offer us a way to pass both the error or the result, passing the responsibility to handle faulty execution path upwards

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s