/ EXERCISE, PROGRAMMING, STYLE

# Composing Exercises in Programming Style

Last week saw us using higher-order functions by passing them as the parameter to another function, and dynamically calling them. The parameter passing is quite nice, but it’s not easy to follow the flow of the program.

This week we are going to keep those functions, but make use of them in a different way, with function composition.

This is the 6th post in the Exercises in Programming Style focus series.Other posts include:

## Function composition

Before you recoil in terror as it brings you bad memories from school, please read on the following: imagine a function `f()` that takes a `X` and returns a `Y`. Imagine another function `g()` that takes a type `Y` and returns a `Z`.

In Kotlin, this looks like the following:

``````fun f(x: X): Y = Y(x)
fun g(y: Y): Z = Z(y)``````

Now, let’s create a new function that calls each of them in turn, and pass the result of the first as the parameter to the second:

``fun composed(x: X): Z = g(f(x))``

This is more or less function composition. In math, this would be written as `g o f`.

## Applying function composition to the exercise

To apply the above composition principle to the task at hand, we will design a method that "pipes" the output of a method to the input of another one. I deliberately used the word pipe, because this is the exact same principle used by the `|` operator in *Nix shells.

For example, those are the first 3 functions that can be defined:

``````fun readFile(filename: String) = read(filename)

fun filterChars(lines: List<String>) = lines
.flatMap { it.split("\\W|_".toRegex()) }
.filter { it.isNotBlank() && it.length >= 2 }

fun normalize(lines: List<String>) = lines.map(String::toLowerCase)``````

To store each step’s result, we create a class with:

• a `value` placeholder
• and the required pipe function - called `bind()` in the Python sample:
``````class TheOne(private var value: Any) {
fun <T, V : Any> bind(function: (T) -> V) = apply {
value = function(value as T)
}
}``````

At this point, the class can be called like that:

``````TheOne(filename)                  (1)
.bind(::filterChars)          (2)
.bind(::normalize)            (2)
// Abridged for brevity``````
 1 Create the class with the initial `value` set to the `filename` 2 Call the `bind()` function, which executes the function passed as a parameter. In turn, this function uses `value` as its parameter, and overwrites it with the result of its own execution.

## Removing state

At this point, the program works and is the exact mirror of the Python sample. However, function composition comes from Functional Programming, and the later eschews mutable state. In the above snippet, the `value` property is constantly overwritten. Let’s remove it, and migrate to a completely immutable process.

The function that needs to be designed:

1. starts from a value of a type
2. executes a function with this value as a parameter
3. and returns the result

This looks like:

``fun <T, V> T.pipe(function: (T) -> V) = function(this)``

The calling code can then be replaced with:

``````filename
.pipe(::filterChars)
.pipe(::normalize)``````

Icing on the cake, this version is fully type-safe. In the previous version, the returned value was the same instance of `TheOne`. Hence, the following compiled, but crashed at runtime:

``````TheOne(filename)
.bind(::filterChars)      (1)
 1 `filterChars` expects a `List` input, but `value` holds a simple `String` at this point

The current version will fail at compile-time:

``````filename
.pipe(::filterChars)       (1)
 1 `filterChars` still expects a `List`, but the compiler is aware of the signature of `pipe()`: `filename` is a `String`, the `T` generic type is a `String`, hence the function passed to `pipe()` should accept a `String` parameter. Because this is not the case, the code won’t compile.

## Conclusion

Modeling a function call as a mathematical function allows to chain them together - this is function composition. Some libraries are designed like that, such as Resilience4J, where every feature is a function: features can be composed together.

Unlike mathematics, function composition in software can be mutable or immutable. In all cases, function composition is definitely a good tool to have in a well-rounded developer’s toolbelt.

The complete source code for this post can be found on Github. #### Nicolas Fränkel

Nicolas Fränkel is a Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Currently working for Hazelcast. Also double as a teacher in universities and higher education schools, a trainer and triples as a book author.