Functional composition
Enhancing RecyclerView with Functional Composition
Published
June 30, 2020
Read time
7 Minutes

Written by
Published
June 30, 2020
Read time
7 Minutes

As an Android developer in Kotlin, I often see devs asking why they should use lambdas and what is the benefit of using them. So let me share the concept of functional composition and its benefits with you.
However before we start with the code, let’s gain some theoretical background. Functional composition, or so called function composition, is a mathematical concept.
In mathematics, function composition is an operation that takes two functions f and g and produces a function h such that h(x) = g(f(x)). In this operation, the function g is applied to the result of applying the function f to x.
From Wikipedia: https://en.wikipedia.org/wiki/Function_composition
Why this is so important you will see later. For now the important part is that we have methods that depend on other methods results.
Example
If you are Android developer, you might have seen this:

This is a very basic implementation of clickListener in RecyclerView. There are a number of issues within this code:
-
Holderinvokeslistenerand obtainsModelfromdatafield ofAdapter– breaks Single Responsibility and Separation of Concerns principles, Adaptercannot rely ondatafield consistency, because it’s modifiable byHolder– breaks Encapsulation ofAdapter,Holderrelies on use of specificAdapter– Tight coupling thus no Reusability is possible.
In the case of RecyclerView‘s Adapter, this is often tolerated. But from my experience, once you learn something bad on a small scale, you will tend to use it on a large scale as well.
Note: Unfortunately, even the presence of lambda doesn’t make this a functional code! It just anonymizes the instance of the listener, which gives a bit more flexibility and independence, but nothing functional.
Functional composition to the rescue!
Let’s adjust the code with the functional composition:

According to definition h(x) = g(f(x)) we can rename our functions to clickComposite(position) = clickListener(dataProvider(position)). The composition consists of calling clickListener with the result of dataProvider applied on the provided position.
As a result, we’ve mitigated all the mentioned issues:
Holderis responsible only for propagating position,Adapterfor provide data on that position – Single Responsibility is satisfied,- the Separation of Concerns is achieved by moving position to Model mapping out of
Holder, - by removing the
innerkeyword we’ve achieved Encapsulation ofAdapter‘sdatafield and also decoupling both classes, allowing reusability ofHolder.
Note: Don’t be fooled with lambdas. This code uses functional principles, but it’s still fully convertible to interfaces. You don’t need lambdas for this. It will be just much uglier.
Higher-order function
If you are an attentive reader you might have noticed, I’ve mixed two terms. Functional composition and function composition.
By the definition h(x) = g(f(x)) we have made a reactive code that was able to call function g with the result of calling f(x). But we didn’t have the real h(x) that can do composition, we had only lambda with that concrete composition, which is still error prone, boilerplate.
To address this, we can advance the previous solution to use a Higher-order function. For that purpose, we need some compose operator. So let’s just rewrite the mathematical definition into Kotlin:

And taste it:

As a result, we have the same benefits from the previous solution, but less boilerplate code. We are able to write Unit tests for the compose function and ensure this code is working correctly. And the readability is also improved (unless you hate math :)).
Conclusion
Comparing the last two examples you might have noticed that the first example defines how the object (Holder) will treat the data, while the following two defines what is object’s (Holder) behaviour – what is his FUNCTION. This is the tiny difference that makes functional programming important.
You should also understand the difference between Functional Composition and Function Composition, how they are achieved, and what they can give you.
Which one should you choose? Well, it’s up to you. In the end, it’s only about what suits you (and your team) the best.
PS: During the publishing process of this article, we found some blur in the understanding of what lambda and functional is.
I would like to dispel some myths. Lambda != functional. Functional code does not require you to use lambdas. You can write functional code with interfaces. You can also write non functional code with lambdas (that was the first example).
Lambdas describe behaviour, while interfaces define also the identity. You can understand lambdas as method polymorphism – they are matching based on function declaration. They are not meant to be used for modeling complexity, but rather to simplify complexity of a simple thing that you would normally achieve by polymorphism.