Currying and Partial Application in Kotlin

Many moons ago, I wrote an article on the feasibility of currying and partial application in Java 8, and asserted that, while it was technically feasible, explicit and thorough type syntax in the language, as well as inflexible operator notation prevented it from being approachable. In comparison, is Kotlin up to the challenge?

Kotlin provides a much more addressable function syntax, and also has a powerful type inferencer. As a result, currying and partial application might just be manage-able.

In the previous article I showed this example of currying using Javascript:

1// JS
2function add(a) {
3    return function(b) {
4        return a + b;
5    }
8add(1)(2); // returns 3.

Here is the same thing in Kotlin:

1fun add(a:Int) = { b:Int -> a+b }
3add(1)(2) // returns 3.

This is quite terse, but harbors a significant amount of information. We can look at it in a longer form so it’s a little easier to grok the first time:

1fun add(a:Int) : (Int) -> Int {
2    return { b: Int -> a + b }

So add is a function that returns a function that takes an int, and returns an int. Internally, that function is defined as a + b.

And, as with the Javascript example where we could do function specialization:

1// JS
2var addOne = add(1);
3var val1 = addOne(2); // returns 3
4var val2 = addOne(3); // returns 4

So can we do this in Kotlin as well:

1val addOne = add(1)
2val val1 = addOne(2) // returns 3
3val val2 = addOne(3) // returns 4

I also showed partial application with Javascript and Java, which is the idea of wrapping a multi-parameter function in such a way that you codify or fix a subset of the functions to create a simpler form. Here it is in Javascript:

 1function add(a, b) {
 2    return a + b;
 5// Partially apply this function in a new function.
 6var addOne = function(b) {
 7    return add(1, b);
10var val1 = addOne(2); // returns 3.

And again, here it is in Kotlin:

1val addOne = { b:Int -> add(1, b) }
2val val1 = addOne(2) // returns 3

Here, the basic “add” function is decorated with another function that fixes the first paramter to 1, but still allows the second function to be passed through. This could easily be done as a proper function rather than an inline “lambda” in this context:

1fun addOne = { b:Int -> add(1,b) }

While this by itself does not make Kotlin a true functional language, it does open the doors to more functional patterns and techniques, as evidenced by many of Kotlins function-oriented libraries.

comments powered by Disqus