How to live in a pure world
Tags: functional, sideeeffects, io, kotlin
Published: 2020-07-15 07:18:46

---
title: How to live in a pure world
published: true
description: Make side effects pure 
tags: #fp #sideeEffects #io #kotlin
//cover_image: https://direct_url_to_image.jpg
---
![To the infinity and beyond](https://dev-to-uploads.s3.amazonaws.com/i/otkry8574bimpmctmhmg.jpg)


Hello folks, 
here I am with a follow-up of the previous article [A matter of purity](https://dev.to/eureka84/a-matter-of-purity-2flj)

In it I talked about what is a **pure function** and why should you even care. 

I can imagine some questions may have arisen while reading it: 

- how to make partial functions total? 
- how to make pure and referentially transparent functions that perform some sort of side effect (like IO)?

Let's address these issues one at a time. 

# Make partial functions total

Just to get everybody on the same page let me recall what a partial function is: 

>given `f: A -> B` f is **partial** if it is not defined **for all** a in A. 

How can one work on `f` to get an `f'` such that `f'` is total? 

Well, there are 2 paths one can take: 

1. restrict f domain A to those elements where f is defined, i.e. 
	> `f': A' -> B` where `A'` is made of all `a in A` such that it exists a `b in B` where `b = f(a)`

	Thinking about `f` as a function we can write in Kotlin or Java this path seems a bit tortuous; 

2. augment B with a synthetic value that maps all a in A where f is not defined 
	> `f': A -> B'` where B' is `B union { epsilon }` and for all a in A where f is not defined then `epsilon = f'(a)`
	
	This second approach is the one we can pursue in our code using data types like `Option` and `Either` because when we say that our function
	
	```kotlin
	val f: (A) -> Option<B>
	```
	
	what we are saying is exactly that whenever we cannot return `Some(a)` we will return `None`. (Same goes for `Either`, whenever we cannot return `Right(a)` we will return `Left(error)`). 
	
So that should give an answer about totality. 

# Make side effects pure

Once we have made our functions total, have we made them pure? 

What about functions performing IO?

Let's see an example 

```kotlin
fun readFileLines(path: String): List<String> = 
	File(path).readLines()
```

We know that this function may throw an IOException so, from what we said above about making partial functions total, we could turn it into 

```kotlin
fun readFileLines(path: String): Either<IOException, List<String>> =
	try {
		File(path).readLines().right()
	} catch (e: IOException) {
		e.left()
	}
```

Now the function is total (you can argue that returning IOException as the error type may not be the best design choice, but we'll leave it like that for the time being).

But is it pure? Is it true that: 

> given the **same** `path` input it will **always** return the **same** `Either` value, be it a `Right` value or a `Left` one?

The answer is no because anytime we call this function we are interacting with the external world and we have no control or knowledge of what this world may look like at any time. 

In the functional universe (well, to be precise, in the Haskell orbiting part) there is an abstraction meant exactly to describe this interaction. Let me introduce you the 

> IO (monad)!

Leaving aside the _scary_ m-word, let's focus on the IO abstraction. 

The idea behind it is simple: given that the interaction with the external world is not predictable, we are going to work with a type that is designed like:

```kotlin
data class IO<A>(run: () -> A) {
	
	fun map<B>(f: (A) -> B): IO<B> = // omitted
	
	fun flatMap<B>(f: (A) -> IO<B>): IO<B> = // omitted
	
	[...]
}
```

Can you see it? All that matters is that `() -> A`. 

Why? 

Because it is as if you are saying: provided that I promise to give you an A, you can transform it via `map`, if your transformation is a **pure** function, or via `flatMap`, if  your transformation has again some kind of interaction with the external world. 

We have transformed the **real**, **unpredictable** interaction with the external world with a description of it, simply introducing a delay. What we gained by doing so is that this description is once again a **value**, and we can play around with values freely. 

> NOTE: Kotlin has a construct built in the language, _suspended functions_, that can be thought a bit as our delay function (`() -> A`). For that reason, the creators and maintainers of Arrow (the functional companion for Kotlin) have decided to redesign their implementation of the IO data type to exploit suspended functions (and coroutines). I promise I will make an article dedicated to it, as soon as I manage to fully understand it myself :D

## Conclusion

> Is it easy to live in a **pure** world? 

That is not really for me to tell you, only you can judge if what you gain is worth the pain (if you want to call it so). Nonetheless, I think that expanding your horizons and knowing about what it means to live in a **pure** world will provide you with a new perspective on how to interact with the world that can be useful also if you choose to remain in an **impure** world. 

I hope to have given you some explanations of concepts you may have heard of but never managed to wrap your head around. 

Well folks, what else to add?  

> To infinity and beyond!