# Functional Programming with Kotlin and Arrow: Getting Started

**Kotlin 1.3, Android 9.0, Other**Kotlin 1.3, Android 9.0, Other

In this tutorial, you will learn the fundamentals of functional programming and how various Kotlin language features enable functional programming concepts. By Massimo Carli.

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

## Contents

## Functional Programming with Kotlin and Arrow: Getting Started

30 mins

- Getting Started
- OOP in a Nutshell
- Types as Abstractions
- Abstracting Identity
- Collaboration
- Immutability
- Moving From Objects to Functions
- Defining Functions
- Function Types
- Applying Higher-Order Functions
- Functions in Kotlin: Considering Special Cases
- Special Case #1: A Function With Nothing
- Special Case #2: The Unit Function
- Special Case #3: Predicate Functions
- Function Composition
- Side Effects
- Pure Functions
- Logger: The FP Way
- Applying Abstraction
- Implementing Composition
- What About Arrow?
- Where to Go From Here?

## Functions in Kotlin: Considering Special Cases

A function defines a way to map values from an input set to values of an output set. For instance, the type `BookMapper<T>`

abstracts all the possible functions that map *Book* objects into instances of type *T*. These sets are theoretically infinite but numerable with some special cases:

- The
*empty*set - A set with a
*single value* - A set with
*two values*

### Special Case #1: A Function With Nothing

An empty set contains no elements. For the moment, call the related type *Empty*. You can define a function type that maps values from *Empty* to and from any other types *T*:

```
typealias FromEmpty<T> = (Empty) -> T
typealias ToEmpty<T> = (T) -> Empty
typealias EmptyId = (Empty) -> Empty
```

When dealing with the *Empty*, problems may arise. Consider this function definition:

```
fun absurd(value: Empty): String = "I'm absurd"
```

The name of this function is *absurd* because it’s a function you can’t invoke. To use it, you need a value for the parameter of type *Empty*. A type corresponds to a set of values, but in this case, the set is empty, and it has no values.

You can define a function that maps values of type *T* to values of type *Empty*, but it can’t return any values for the same reason.

At this point, you should recognize the *Nothing* type. Its source code should show that it represents a type but not a class, in the general sense, because you can’t instantiate it:

```
public class Nothing private constructor()
```

### Special Case #2: The Unit Function

Another special case happens when the set contains only one element. This type can be used for the input or the output, and in Kotlin corresponds to the *Unit* type. *Unit* is not just a type, it’s also the single existing instance for that type. Look at this example:

```
typealias unit<T> = (T) -> Unit
```

This code abstracts all the possible functions that receive a generic type *T* as input and returns the only existing object of the *Unit* type, which is the *Unit* value. This is the *unit* function.

It’s interesting how these types of functions are mapped into Java functions, which return *void*. In Kotlin, they’re returning something, but it’s always the same instance unit. For proof, look at the source code where it’s implemented as a singleton:

```
public object Unit {
override fun toString() = "kotlin.Unit"
}
```

### Special Case #3: Predicate Functions

What about a set with only two values? You already know the type for this special set: it’s `Boolean`

. A function that maps values to this set is a *Predicate*, represented like this:

```
typealias Predicate<T> = (T) -> Boolean
```

Now that you have a handle on the basics of abstraction, consider the concept of *composition*.

## Function Composition

In OOP, objects interact with each other using their interfaces. Collaboration between functions is called *Composition*.

Create a *Composition.kt* file and add this type definition, which represents every possible function from *A* to *B*:

```
typealias Func<A, B> = (A) -> B
```

Then, write:

```
val getPrice: Func<Book, Price> = { book -> book.price }
val formatPrice: Func<Price, String> =
fun(priceData: Price) = "value: ${priceData.value}${priceData.currency}"
```

The former, of type `Func<Book,Price>`

returns the price of a book, and the latter, of type `Func<Price,String>`

, provides a formatted version of the same price. The *output* type of the former is the same as the *input* type of the latter.

Create another function called *after* whose type is `Func<Book, String>`

, which invokes the function `formatPrice`

*after* the function `getPrice`

like this:

```
infix fun <A, B, C> Func<B, C>.after(f: Func<A, B>): Func<A, C> = { x: A -> this(f(x)) }
```

This invokes a function by passing the output value of the previous function as a parameter. In other words, it implements *function composition*. You can then compose the two functions in two different ways:

```
fun main() {
// 1
val result: String = formatPrice(getPrice(books[0]))
println(result)
// 2
val compositeResult: String = (formatPrice after getPrice)(books[0])
println(compositeResult)
}
```

This demonstrates an important difference:

- Invoke the
*formatPrice*function using the output of the*getPrice*function. - Invoke the function that is the composition of the
*formatPrice*and*getPrice*functions.

Build and run. You’ll get an output like this which proves the equivalence of the two expressions:

```
value: 39.26£
value: 39.26£
```

## Side Effects

Remember, you’re studying functions because you had a data race problem to solve. To understand how functions can solve the data race problem, create a new *Pure.kt* file with this code:

```
class Logger {
var log = StringBuilder()
fun log(str: String) {
log = log.append(str).append("\n")
}
}
```

This is a `Logger`

class, whose responsibility is to log operations. Each time you invoke the `log`

method, you append a new line.

Suppose you want to log the operation for the functions `getPrice`

and `formatPrice`

that you created in the previous section. You might write:

```
val logger = Logger()
val getPriceWithLog: Func<Book, Price> = {
logger.log("Price calculated for ${it.ISDN}")
it.price
}
val formatPriceWithLog: Func<Price, String> = {
logger.log("Bill line created")
"value: ${it.value} ${it.currency}"
}
```

Here, you created a `Logger`

instance to use in the function bodies. Hey! You’re using functions, but you still have a shared resource with a shared state — the *log*. You can see this by adding and running the `main`

function below:

```
fun main() {
formatPriceWithLog(getPriceWithLog(books[0]))
println(logger.log)
}
```

Running this code you get:

```
Price calculated for 8850333404
Bill line created
```

When you invoke the `getPriceWithLog`

or `formatPriceWithLog`

functions, you’re changing the log and upsetting the world where other functions can run. This is called a *side effect*. So not all functions are a solution to the data race problem in a multithreaded environment.

Even worse: What if the output of the function itself depends on the side effect? How can you test these functions? You need something more.

## Pure Functions

Not all functions are good. Some of them still share data, and sharing data doesn’t work in a multithreaded environment. However, you can define a function that doesn’t perturb the environment where it’s executed. For that, you need a *pure function*, which is a function with no side effects.

Pure functions have outputs that depend on their input. Repeatedly invoking a pure function with the same input always yields the same output. They don’t share a state, and they have everything they need in their parameters.

Pure functions are like a lookup table. They are data, and you can replace the function invocation with its output. This is *referential transparency*. It’s useful because it allows the compiler to perform optimizations, which wouldn’t be possible otherwise.

Some languages, like Haskel, force you to define pure functions, but Kotlin is more flexible. How can you fix the previous logger problem, then?