What Are Higher Order Functions and Receiver Types in Kotlin?

If you have been programming Java, especially within Android, for a long time, you would know that higher order functions are not really a thing. They are, in such a way that you can pass around a functional interface, however those are not true functions (a function literal to be specific). Fear not, because Kotlin is here and allows you to do just that.

A basic higher order function

Kotlin allows us to define a function which takes a function (a literal) as a parameter. The syntax for this looks like the following:

We’ve written an empty function which takes a function as a parameter (simply named function  in our case) and does nothing. You should notice that we wrap our argument types in brackets, if we wanted multiple parameters, we’d use a comma to separate them. Right now, this function isn’t doing anything. Let’s change that.

From our main  method, we are now passing a lambda function to functionTest() . We can see that it takes value s  and returns s.plus("!") . All this lambda is doing, is just taking a String and returning the same String appended by a “!”.

A little more complex…

Higher order functions can grow to be more complex. Let’s see an example where we take a function with multiple parameters on top of having multiple statements in the return clause.

If you’re new to Kotlin, this can look a little confusing. Especially the last line of our main  method. For starters, the last line of our return clause is what is returned. We do not have to include the return  keyword for this – it can be omitted. So, we’re allowed to have an unlimited number of statements, as long as the last line is what is to be returned (a String in this case). Also, as previously stated, we separate our argument types with a comma which are enclosed within brackets. The function we pass to functionTest()  simply returns a String appended by itself times.

Literals with a receiver type

When writing function literals in Kotlin, we have the option of specifying a receiver type. Essentially what this allows us to do is to directly call methods on our receiver object within the function’s body. Let’s look at an example – we’ll start by rewriting the first function from the beginning of this article.

Right off the bat, this looks a lot cleaner albeit a bit more confusing. We are basically calling plus  directly on the String we pass in, any reference to the receiver object can be omitted (such as the keyword, this ). You may also notice the lack of the ->  symbol and return type. Since we omit parameter types within our brackets, this isn’t needed. We can simply call a String (our receiver type) function which returns a String.

As with literals with no receivers, we are allowed to have multiple parameters. Let’s do this by rewriting the second example from earlier.

Now we are calling the function directly on our String, which is a bit different that what we were doing before. Previously, we were passing two different arguments in to our function, now only one. Since we are specifying a receiver object of type String , we now only need our Int  value as a parameter. We also reference our receiver object with the this  keyword.

This line basically says that our parameter, function , is “a String function which takes an Int and returns a String”. This is how we are able to call it directly on s . The concept of receiver types is quite similar to extension functions.

 

 

Liked the article? Share it!

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of