# 5 Higher-Order Functions Written by Massimo Carli

In the previous chapters, you learned that a lambda expression is basically a function that can be used as a value. This means you can define a lambda expression and assign it to a variable. More importantly, you can pass a lambda expression as an input parameter or return the value of another function. Passing lambdas as parameters describes higher-order functions, which are the main topic of this chapter.

Here, you’ll learn:

• The difference between an imperative and declarative approach.
• What higher-order functions are.
• What a functional interface is and what SAM means.
• Why interfaces with a single operation are fundamental in functional programming.
• How inline works when using higher-order functions.

You’ll learn all this while using the Kotlin language and solving some fun exercises. Open up the starter project for this chapter in IntelliJ and keep reading.

## Imperative vs. declarative approach

Before diving into the study of higher-order functions in Kotlin, it’s important to mention why they’re fundamental and why you should use them. One of the main reasons is that higher-order functions allow you to write your code in a declarative way.

But what does that mean? An example will make things easier.

Consider the following list of email address candidates that you’ll find in Imperative.kt in this chapter’s material:

``````val emails = listOf(
"email@emmmaail.com",
"max@fgh.it",
"hsajdkjshh",
"mike@mcarli.it",
"first.second@ggg.com",
"test@test.co.uk",
"12345@qqq.com",
"123.45",
"12345@a.b.c.d",
"fp_is_great@funprog.com",
"aaaaaaaaa.bbbbb@cccc.com",
"aaaaaaacccc.com",
"valid@jjjj.lll",
)
``````

Now, suppose you want to write a function that:

2. Uses only email addresses with more than 10 characters.
3. Takes just the first five valid email addresses.

A first approach is the imperative one. In the same Imperative.kt file, write the following code:

``````fun imperative(emails: List<String>): List<String> = // 1
mutableListOf<String>() // 2
.apply {
for (email in emails) { // 3
if (EMAIL_REG_EX.matches(email) && email.length > 10) { // 4
if (size >= 5) { // 5
break
}
}
}
}
``````

In this code, you:

1. Define `imperative` as a function that returns the first five valid email addresses longer than 10 characters.
2. Initialize the `List` you’ll return as the result.
3. Iterate over all the email addresses in input.
4. Check if the email is valid using the available regular expression `EMAIL_REG_EX`. Here, you also check if the email has a minimum length of over 10.
5. Stop when it gets `5` email addresses.

``````fun main() {
println(imperative(emails))
}
``````

And you get the following output:

``````[email@emmmaail.com, mike@mcarli.it, first.second@ggg.com, test@test.co.uk, fp_is_great@funprog.com]
``````

This is an example of an imperative approach or algorithmic programming. Here, you write the code specifying the steps the computer must take to accomplish the goal. In this case, you’re telling the computer exactly what steps to execute in a language it understands. If you want to change the criteria for filtering the emails, you need to first digest the code, apply the changes and update the unit tests. In this case, the goal you want to achieve is simple, but in many other cases, this could be a problem.

Note: For an even more imperative approach, you can replace the enhanced `for` loop:

``````for (email in emails){...}
``````

With:

``````for (i in 0 until email.size){
val email = emails[i]
// ...
}
``````

The declarative approach is closer to how humans think. Now, add the following code to Declarative.kt:

``````fun declarative(emails: List<String>): List<String> = // 1
emails
.filter { EMAIL_REG_EX.matches(it) } // 2
.filter { it.length > 10 } // 3
.take(5) // 4
``````

In this case, you:

1. Define `declarative` with the same signature as `imperative`.
2. Use `filter` to remove the invalid email addresses.
3. Use `filter` again to remove email addresses shorter than or equal to 10 characters.
4. Take the first `5` email addresses using `take`.

Now, add and run the following code:

``````fun main() {
println(declarative(emails))
}
``````

And you get exactly the same output:

``````[email@emmmaail.com, mike@mcarli.it, first.second@ggg.com, test@test.co.uk, fp_is_great@funprog.com]
``````

When you look at the code, you realize it’s just a description of the steps you want to do, which follows the initial requirements. You take five email addresses from the ones you filtered because they matched the email regular expression and were longer than 10 characters. You might already see some of the declarative approach’s advantages, but you can do even better than this.

The declarative approach improves code readability. In the same Declarative.kt file, add the following code:

``````fun isEmailValid(email: String) = // 1
EMAIL_REG_EX.matches(email)

fun isEmailLongEnough(email: String) = // 2
email.length > 10

fun moreDeclarative(emails: List<String>): List<String> =
emails
.filter(::isEmailValid) // 3
.filter(::isEmailLongEnough) // 4
.take(5)
``````

In this case, you:

1. Define `isEmailValid`, which is a pure function that checks if the input email address is valid.
2. Create `isEmailLongEnough` to check the length of the email address.
3. Use the reference `::isEmailValid` as the parameter of the first `filter`.
4. Use `::isEmailLongEnough` as the parameter of the second `filter`.

This is so declarative that you can read the code as if it were in normal, spoken English. You basically:

``````filter the valid emails
filter the emails that are long enough
take 5 of them
``````

`filter` is a perfect example of a higher-order function, because it’s a function that accepts another function as an input parameter. Look at the source code for `filter`, and you’ll find the following:

``````public inline fun <T> Iterable<T>.filter(
predicate: (T) -> Boolean
): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
``````

Besides the implementation details, it’s important to see how:

1. It’s an extension function for `Iterable<T>`.
2. The input parameter is a predicate of type `(T) -> Boolean`. As you learned in Chapter 2, “Function Fundamentals”, a predicate is any function that returns a `Boolean`. In this case, the predicate is a lambda accepting an object of type `T` as input, which is the type parameter for `Iterable<T>`.

In the rest of the book, you’ll see many examples of this, and you’ll see how functional programming and the declarative approach get along. :]

## Higher-order functions

By now you should know what a higher-order function is — you’ve already written some of them. The most important one you saw in Chapter 2, “Function Fundamentals” is:

``````inline infix fun <A, B, C> Fun<B, C>.after(
crossinline f: Fun<A, B>
): Fun<A, C> = { a: A ->
this(f(a)) // HERE
}
``````

This is an extension function on `Fun<B, C>`, which receives as input another function of type `Fun<A, B>` and returns a function of type `Fun<A, C>`, which is the composition of the two.

In this next section, you’ll see some more examples of higher-order functions, which:

• Accept a lambda expression as input.
• Return a lambda expression as an output value.
• Use lambda expressions as input and as output values.

You’ll also make everything fun with some nice exercises.

### Accepting a lambda expression as input

You’ve already met one example of a higher-order function accepting a lambda expression as input. Now to write more. Open SimpleHoF.kt in the material for this project, and write the following code:

``````fun Int.times(fn: (Int) -> Unit) = (1..this).forEach(fn)
``````

This function executes the lambda the provided number of times. In this code, you define:

• `times` as an extension function for the `Int` type.
• `fn` as an input parameter of type `(Int) -> Unit`, which is invoked the number of times described by the receiver. Remember that, in this case, the receiver is the `Int` value you invoke `times` on. In the case of `10.times{}`, the receiver is `10`.
• The range as `1..this`, and you iterate over it using `forEach` to execute `fn` that number of times.

You can test how `times` works by adding and running this:

``````fun main() {
10.times {
print(" \$it")
}
}
``````

The output you get is:

`````` 1 2 3 4 5 6 7 8 9 10
``````

You probably think that, with the previous code, you cheated a little bit. :] `forEach` is another higher-order function Kotlin provides as an extension function for `Iterable<T>`, like the `filter` you met earlier:

``````public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
``````

OK, assuming you don’t want to use an existing higher-order function, you can replace the previous implementation with the following imperative-ish code:

``````fun Int.times(fn: (Int) -> Unit) {
var i = 1
while (i <= this) {
fn(i++)
}
}
``````

When you run `main`, you get the same output:

`````` 1 2 3 4 5 6 7 8 9 10
``````

Exercise 5.1: Kotlin provides you with `first`, which returns the first element of `Iterable<T>` for which a predicate you provide in input evaluates to `true`. Remember that `Iterable<T>` is the abstraction of all the collections providing `Iterator<T>` implementation.

``````public interface Iterable<out T> {
public operator fun iterator(): Iterator<T>
}
``````

`Iterator<T>` allows you to iterate over all the elements of a collection in a way that doesn’t depend on the collection implementation itself:

``````public interface Iterator<out T> {

public operator fun next(): T

public operator fun hasNext(): Boolean
}
``````

The current `first` signature is:

``````public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T
``````

Kotlin doesn’t allow you to override the current extension function on `Iterable<T>`. So, how would you implement `first` on `Array<T>`?

The current implementation of `first` throws an exception if the collection is empty, so there’s no first `T`. How would you implement the function `firstOrNull` on `Array<T>` returning `null` in such a case?

Give it a try and check the challenge project or Appendix E to see how you did.

### Implementing the strategy pattern in a functional way

Hey, isn’t this a book about functional programming? What does the strategy pattern have to do with this? As you know, design patterns describe a general and reusable solution to a commonly occurring problem within a given context. In particular, the strategy pattern is a behavioral pattern that defines a family of algorithms, encapsulates each one and makes them interchangeable. Sorting is a typical example. Open Strategy.kt and write the following code:

``````fun bubbleSort(values: IntArray) {
for (i in values.size - 1 downTo 0) {
for (j in 0 until i) {
if (values[j] > values[j + 1]) {
swap(values, j, j + 1)
}
}
}
}
``````

This function sorts an input `IntArray` using the bubble sort. Understanding how it’s sorting is less important here than knowing that it’s sorting `Int`s. Note, the `swap` function is already available in Util.kt.

You can test how it works by executing the following:

``````fun main() {
val array = intArrayOf(10, 5, 2, 7, 8, 3)
bubbleSort(array)
array.printAll()
}
``````

`printAll` is a function in Util.kt. Run this code, and you get what you expect:

`````` 2 3 5 7 8 10
``````

It’s important to note that you can use the bubble sort to sort anything, not just `Int`. What you need is just a way to understand when a value is greater than another value of the same type. How, then, can you abstract `bubbleSort` so you can use it with any array of values of type `T`?

Note: The bubble sort definitely isn’t the most performant sorting algorithm. It’s used here because it does not need a lot of code.

Note: If you want to learn more about algorithm and data structures in Kotlin, Data Structures & Algorithms in Kotlin is the best choice.

To solve this problem, you need to:

• Make `bubbleSort` generic.
• Provide `bubbleSort` what it’s missing: a way to understand if one `T` is greater than another `T`.

In the same file, replace the previous code with the following:

``````fun <T> bubbleSort(
values: Array<T>, // 1
isLarger: (T, T) -> Boolean // 2
) {
for (i in values.size - 1 downTo 0) {
for (j in 0 until i) {
if (isLarger(values[j], values[j + 1])) { // 3
swap(values, j, j + 1) // 4
}
}
}
}
``````

In this code, you:

1. Define `bubbleSort` as a generic function with the type variable `T`.
2. Pass the strategy as a lambda function of type `(T, T) -> Boolean`, which returns `true` if the first value is greater than the second.
3. Use the `isLarger` lambda expression to compare each pair of values in the array.
4. Swap the values, if needed, using the `swap` overload you find in Util.kt.

To test the previous code, write:

``````fun main() {
val array = arrayOf(10, 5, 2, 7, 8, 3)
bubbleSort(array) { first, second ->
first > second
}
array.printAll()
}
``````

Run this code, and you again get:

`````` 2 3 5 7 8 10
``````

Exercise 5.2: The command pattern is another important design pattern that defines abstractions like `Command` and `CommandExecutor`. `Command` abstracts every possible operation that `CommandExecutor` can run. In other words, a `Command` represents a task and you can pass a `Command` to a `CommandExecutor` to run it. How would you represent them in a functional way?

Optionally, can you also provide a way to “redo” the most recent `Command`?

## Functional interfaces

In the previous chapters, you learned the concept of function type. If you consider the previous strategy pattern example, you could’ve defined the type for the predicate parameter using `typealias`, like this:

``````typealias IsLarger<T> = (T, T) -> Boolean
``````

With this, the bubble sort example would become:

``````fun <T> bubbleSort(
values: Array<T>,
isLarger: IsLarger<T> // HERE
) {
for (i in values.size - 1 downTo 0) {
for (j in 0 until i) {
if (isLarger(values[j], values[j + 1])) {
swap(values, j, j + 1)
}
}
}
}
``````

As you learned in Chapter 2, “Function Fundamentals”, a function type is basically a way to represent a function in terms of:

• Input parameters and their type
• Return type

With `(T, T) -> Boolean`, you’re basically representing the type of all the functions with two parameters of type `T` returning a `Boolean`. With the `typealias` keyword, you just gave that type the name `IsLarger<T>`.

Kotlin allows you to do something similar with functional interfaces. You find the same concept with the acronym SAM, which stands for single abstract method. For instance, open FunctionalInterface.kt and write the following definition:

``````fun interface IsLarger<T> { // 1
fun isLarger(a: T, b: T): Boolean // 2
}
``````

In this case, you:

1. Use the `fun` keyword as a qualifier for the `IsLarger<T>` interface.
2. Define `isLarger` as the only abstract function for the functional interface.

Using the previous definition, you can add the following code to the same file:

``````fun <T> bubbleSortFI( // 1
values: Array<T>,
largerStrategy: IsLarger<T> // 2
) {
for (i in values.size - 1 downTo 0) {
for (j in 0 until i) {
if (largerStrategy.isLarger(values[j], values[j + 1])) { // 3
swap(values, j, j + 1)
}
}
}
}
``````

In this case, you:

1. Create `bubbleSortFI` as a new version of the previous `bubbleSort`.
2. Define the strategy as a parameter of type `IsLarger<T>`.
3. Invoke `isLarger`, which is the operation you defined in `IsLarger<T>`.

Now, you can test `bubbleSortFI` in two different ways:

• Using `IsLarger<T>` as a normal lambda expression.
• Creating an `IsLarger<T>` implementation instance.

It’s useful to look at both.

### Functional interface as a lambda expression

Because you defined `IsLarger<T>` as a functional interface, you can use the same syntax you’d use with lambda expressions. Add the following code to the same FunctionalInterface.kt file:

``````fun main() {
val array = arrayOf(10, 5, 2, 7, 8, 3)
bubbleSortFI(array) { first, second -> // HERE
first > second
}
array.printAll()
}
``````

Here, you pass the parameter of type `IsLarger<T>` as a normal lambda expression the same way you did when using `typealias`.

### Functional interface instances

Again, because you defined `IsLarger<T>` as a functional interface, Kotlin provides a very handy syntax in case you want to create an implementation instance of the fly. Replace the previous code in FunctionalInterface.kt with:

``````fun main() {
val array = arrayOf(10, 5, 2, 7, 8, 3)
val largerStrategy = IsLarger<Int> { first, second -> // HERE
first > second
}
bubbleSortFI(array, largerStrategy)
array.printAll()
}
``````

Like in the previous example, although `IsLarger<T>` is an interface, you can quickly create an implementation instance using a syntax like:

``````   FunctionInterfaceType { /* Lambda expression for the SAM */}
``````

So, what’s the difference between the definition of a function type using `typealias` and a functional interface?

### Functional interface vs. typealias

It’s crucial to note how `typealias` doesn’t introduce a new type at all. It just allows you to give a different name to an existing type. On the other hand, when you define a functional interface, you’re creating a new type.

Note: Remember that `typealias` definitions aren’t visible from Java.

The difference between a simple interface and a functional interface is the presence of a single abstract method (SAM), which you provide using the same syntax you use for lambda expressions.

To better understand their differences, open FunctionalVsLambda.kt and add the following code:

``````typealias SinglePredicate<T> = (T) -> Boolean // 1

fun <T> SinglePredicate<T>.whoAmI() = println("I'm a typealias") // 2

fun main() {
val isEven = { number: Int -> number % 2 == 0 } // 3
isEven.whoAmI() // 4
}
``````

Here, you just:

1. Give the name `SinglePredicate<T>` to any function receiving a single parameter of type `T` and returning a `Boolean`.
2. Define `whoAmI` as an extension function for `SinglePredicate<T>`, which just prints a message saying that the receiver type is `typealias`.
3. Define the `isEven` lambda, which returns `true` if an `Int` value you pass as a parameter is even. Note how you’re just creating a lambda with no relation to the name `SinglePredicate<T>` you defined earlier. It’s just a lambda receiving an `Int` and returning a `Boolean`.
4. Invoke `whoAmI` on the previous lambda.

Compile and run the previous code, getting:

``````I'm a typealias
``````

This is because the definition of `whoAmI` above would be exactly the same as:

``````fun <T> ((T) -> Boolean).whoAmI() =
println("I'm a typealias")
``````

Now, add the following code to the same file, replacing the existing `main` function:

``````fun interface ISinglePredicate<T> { // 1

fun accept(value: T): Boolean // 2

fun other() { // 3
println("I can have other methods")
}
}

fun <T> ISinglePredicate<T>.whoAmI() = // 4
println("I'm a functional interface")

fun main() {
val isEvenFI = ISinglePredicate<Int> { number -> number % 2 == 0 } // 5
isEvenFI.whoAmI() // 6
isEvenFI.other() // 7
}
``````

In this case, you:

1. Create `ISinglePredicate<T>` as a functional interface.
2. Define `accept` as the single abstract method for `ISinglePredicate<T>`.
3. Also define `other`, proving that a functional interface must have one and only one abstract method, but it can also have other methods. A small note about these methods later.
4. Create the same extension method, `whoAmI`, which prints the fact that this is about a functional interface.
5. Create `isEvenFI` as an `ISinglePredicate<Int>` implementation using the handy syntax mentioned earlier, recalling the lambda expressions.
6. Invoke `whoAmI` on `isEvenFI`.
7. Also invoke `other` on the same `isEvenFI`.

When you run this code, you get:

``````I'm a functional interface
I can have other methods
``````

This proves that a functional interface is conceptually very similar to a function type you define using `typealias`, but it:

1. Allows you to define a new type.
2. Is more type-safe because, like in the previous example, it allows you to define extension methods for a very specific type of function. The `whoAmI` on the type alias works for any function with one parameter returning `Boolean`. The `whoAmI` on `ISinglePredicate<Int>` works just on instances of the same explicit type.
3. Allows you to define one and only one operation. The others can be methods working as default method implementations for an interface.
4. Invokes the abstract method of the functional interface. To achieve this, you need to state its name explicitly. With the function you define using `typealias`, you just use `()` or `invoke`. With `ISinglePredicate<T>`, you need to call `accept`.

Note: In theory, an interface doesn’t define any methods but just operations, which are public and abstract by definition. When you read the method of the interface, it means methods adding something more to the one the interface defines through its operations. An example of this is:

``````interface Reader {
TODO("Call readChar() until it returns null")
}
}
``````

Here, `readChar` is the operation and `readString` is the method.

Exercise 5.3: Can you implement `Reader` in the previous note using a function interface? How would you test it?

### Interfaces with multiple operations or methods

Exercise 5.3 should make you think about the relationship between functional programming and the concept of interfaces with multiple operations. Why do you think interfaces with a single operation (SAM) are so important?

The answer is very simple, and it can be summarized with the concepts you find in the SOLID principles. You won’t revisit all of them here because it’s not the main topic, but just think about the meaning of the `I` there, which stands for the interface segregation principle.

This basically states that no clients should be forced to depend on methods they don’t use. Functional interfaces, or lambda expressions, define a single operation and make it impossible for clients to depend on the lambda expressions if they don’t use those functions.

At this point, you might argue that using just SAM would make it difficult to implement interfaces like `Reader`. That’s not the case at all — and you’ll prove it. :] Open Solid.kt and add the following code to define `CharReader` as the interface with the sole responsibility of providing a single `Char` at a time.

``````fun interface CharReader {
}
``````

If you need to read a `String`, you can use the most fundamental principle of functional programming: composition. In the same file, add the following code:

``````fun interface StringReader {
}
``````

With this, you can implement `StringReader` by adding some code that’s basically the same as what you probably implemented in Exercise 5.3:

``````val stringReader = StringReader { charReader ->
val result = StringBuilder()
do {
if (nextChar != null) {
result.append(nextChar)
}
} while (nextChar != null)
result.toString()
}
``````

To make everything more functional, add:

``````fun String.toCharReader(): CharReader {
var pos = 0
if (pos < this.length) this[pos++] else null
}
}
``````

This is an extension function on `String` returning a `CharReader` you can use like this:

``````fun main() {
}
``````

Run this code, and you get:

``````This is String!
``````

In this single line of code, you:

1. Create `CharReader` from `String`.
2. Use `stringReader` to read `String` back from `CharReader`.
3. Print `String`.

Thinking functionally, you managed to apply the interface segregation principle, splitting `Reader` into two different functional interfaces, `CharReader` and `StringReader`, reducing the dependency drastically.

Note: In Chapter 8, “Composition”, you’ll also learn to improve that code further. It has too many parentheses `()` and can be made more readable.

### Returning a lambda expression as an output value

The return value of a higher-order function can also be a function. Open ReturnFunction.kt and write the following code:

``````fun countFrom(start: Int): () -> Int { // 1
var count = start // 2
return { // 3
count++
}
}
``````

This function:

1. Has an input parameter of type `Int` and returns a function of type `() -> Int`.
2. Initializes `count` to the value of the `start` parameter.
3. Returns a function that returns `count` and then increments its value.

You can test `countFrom` with the following code:

``````fun main() {
val countFromFive = countFrom(5)
println(countFromFive())
println(countFromFive())
println(countFromFive())
}
``````

Run it, and you get:

``````5
6
7
``````

As you see, `countFrom` initializes `count`, which is then captured by the lambda it returns. All the variables outside the scope of a lambda function that the lambda can access represent its closure.

As in the previous example where `count` is incremented, the lambda can access its closure and, if not constant, can also modify it.

Exercise 5.4: Implement an extension function `isEqualsPredicate` on the generic type `T` that returns a predicate that tests if a given value is equal to the same `T`. The signature should be the following:

``````fun <T> T.isEqualsPredicate(): (T) -> Boolean
``````

How would the same function be different if you use the following functional interface?

``````fun interface SinglePredicate<T> {
fun accept(other: T): Boolean
}
``````

## Using lambda expressions as input and output

Functions with a lambda both as a return value and as an input parameter are the most interesting and fun (pun intended :]). You’ve actually seen many of these, and you’ll find many more ahead in the book.

As a simple example here, you can keep playing with `Predicate`. Open Predicates.kt and write the following code:

``````fun interface Predicate1<T> {
fun accept(value: T): Boolean
}
``````

Note: In this chapter, to make different examples coexist in the same project, sometimes you need to use a different name for the same concept. That’s why you append `1` to `Predicate` here. Of course, you wouldn’t do the same in your project.

This is a single functional interface for a predicate with a single parameter you’ve already met many times, such as during Exercise 5.4. Imagine, now, that you want to create a function `and` that accepts as input two `Predicate1<T>`s and returns another one, which is the logical and of the two. To be true, both predicates must be true.

You already know how to do this. In the same Predicates.kt file, add the following code:

``````infix fun <T> Predicate1<T>.and(
other: Predicate1<T>
): Predicate1<T> = // 1
Predicate1 { value ->
this.accept(value) && other.accept(value) // 2
}
``````

In this code, you simply:

1. Create an infix extension function `and` on `Predicate1<T>`.
2. Return another `Predicate1<T>`, which evaluates the first one and, if true, `other`.

In the same way, define `or` like this:

``````infix fun <T> Predicate1<T>.or(
other: Predicate1<T>
): Predicate1<T> =
Predicate1 { value ->
this.accept(value) || other.accept(value)
}
``````

You can use the same approach used in Exercise 5.4 with the following code:

``````fun <T> T.isEqualsPredicate1(): Predicate1<T> = // 1
Predicate1 { value -> this == value }

fun <T> Iterable<T>.filterWithPredicate(predicate: Predicate1<T>) = // 2
filter(predicate::accept)

fun main() {
val predicate = 4.isEqualsPredicate1() or 5.isEqualsPredicate1()  //  3
listOf(1, 2, 3, 4, 4, 5, 6, 7, 8, 8)
.filterWithPredicate(predicate) // 4
.forEach(::println)
}
``````

In this code, you:

1. Define `isEqualsPredicate1` using `Predicate1<T>`.
2. Create `filterWithPredicate` on `Iterable<T>` for filtering values using `Predicate1<T>` instead of `(T) -> Boolean`.
3. Use the `or` you created earlier to create `Predicate1<T>` for filtering values `4` and `5`.
4. Use `filterWithPredicate` with `predicate`.

Run this code, and you get:

``````4
4
5
``````

This is really fun!

Exercise 5.5: Can you implement the same logic for implementing the example in the Imperative vs. declarative approach section using the definitions of `Predicate1<T>` and `filterWithPredicate`? Given a list of email addresses, you need to:

• Filter the valid email addresses.
• Filter the email addresses that are long enough.
• Take the first five of them.

Give it a try and check the solution in Appendix E.

### Higher-order functions and the inline keyword

In Chapter 3, “Functional Programming Concepts”, you learned about the convenience of using an inline keyword for lambda expressions or pure functions in general. When you just inline a pure function, IntelliJ warns you about the insignificant performance benefits. The same message also mentions that this isn’t the same if the lambda was passed as an input parameter to a higher-order function. What does the compiler mean by this?

Open Inline.kt and add the following code:

``````fun executor(fn: () -> Unit) {
fn()
}

fun main() {
executor { println("Hello World!") }
}
``````

In this very simple code, you:

1. Define `executor`, which just executes the lambda you pass as an input parameter.
2. Invoke `executor` in `main`.

In this case, you don’t need to run this code, but repeat the same process you followed in Chapter 3, “Functional Programming Concepts” for the Kotlin decompiled code. When you do so, you end up with something like this:

``````public final class InlineKt {
public static final void executor(@NotNull Function0 fn) { // 1
Intrinsics.checkNotNullParameter(fn, "fn");
fn.invoke();
}

public static final void main() {
executor((Function0)null.INSTANCE); // 2
}

// \$FF: synthetic method
public static void main(String[] var0) {
main();
}
}
``````

As you see:

1. `executor` becomes a Java static method with `Function0` as an input parameter.
2. `main` contains the simple invocation of `executor`.

This is what you’d normally expect. Now, just add the `inline` keyword to `executor` like this:

``````inline fun executor(fn: () -> Unit) { // HERE
fn()
}
``````

The first thing to note is that the IntelliJ warning you got in Chapter 3 doesn’t show up.

Check the decompiled code, and you see that `main` becomes:

``````   public static final void main() {
int \$i\$f\$executor = false;
int var1 = false;
String var2 = "Hello World!";
boolean var3 = false;
System.out.println(var2); // HERE
}
``````

You can see how `main` no longer has an `executor` invocation. There’s not even the invocation of the `fn` you pass as a parameter. The Kotlin compiler has copied the content of `fn` exactly where the previous `executor` invocation was.

The inlined `executor` is very simple, but if it contained more code, the resultant bytecode would also need much more space. On the other hand, you could return to the warning situation using the `noinline` keyword like this:

``````inline fun executor(noinline fn: () -> Unit) { // HERE
fn()
}
``````

In this case, the Kotlin compiler would complain again, like this:

This is because the decompiled code would be like the initial one.

### Non-local returns

Inlining can be useful for another reason, though. Update the code in Inline.kt like the following:

``````fun executor(fn: () -> Unit) {
fn()
}

fun main() {
executor {
var count = 0
while (true) {
count++
if (count > 5) {
return // ERROR
}
}
}
println("The End!")
}
``````

If you don’t inline `executor`, the Kotlin compiler will complain because it doesn’t know from what context it should actually `return`.

Here, you have two options:

1. Use the label `return@executor` specifying that you want to exit from `executor`.
2. Inline `executor`.

In the first case, you can write:

``````fun main() {
executor {
var count = 0
while (true) {
count++
if (count > 5) {
return@executor
}
}
}
println("The End!")
}
``````

In the second case, you can just inline `executor` like this:

``````inline fun executor(fn: () -> Unit) {
fn()
}
``````

You must be very careful, though, because the behavior of your program differs in the two cases.

When you use `return@executor`, you’re saying that when you reach `return`, you’re exiting from the body of `executor`. Run `main`, and you get:

``````The End!
``````

If you inline `executor`, you’re copying `return` in `main`, and reaching it means exiting from `main`. If you run the code, you get nothing because the `println` statement won’t be reached.

### The crossinline keyword

For completeness’ sake, it’s useful to look at the following code:

``````fun executor(fn: () -> Unit) { // 1
fn()
}

inline fun executorExecutor(fn: () -> Unit) { // 2
executor {
fn() // ERROR
}
}
``````

Here, you note that:

1. `executor` isn’t inlined.
2. `executorExecutor` is inlined and invokes the `fn` it receives as an input parameter using `executor`.

As you can see, the Kotlin compiler is complaining: Figure 5.4: Can't inline 'fn' here; it may contain non-local returns

The message in Figure 5.4 explains everything.

The reason is that the compiler doesn’t know how to handle `fn` non-local returns and suggests a solution of introducing the `crossinline` keyword to the parameter like this:

``````inline fun executorExecutor(crossinline fn: () -> Unit) {
executor {
fn()
}
}
``````

This informs the Kotlin compiler that the lambda you pass as an input parameter of `executorExecutor` can’t contain any non-local return. If it does, you get an error:

If you really want to allow `return` in `fn`, you can simply use `inline` for both `executor` and `executorExecutor`:

``````inline fun executor(fn: () -> Unit) { // HERE
fn()
}

inline fun executorExecutor(fn: () -> Unit) { // HERE
executor {
fn()
}
}
``````

## Challenges

In this chapter, you learned a lot about higher-order functions that are basically functions of functions. You’ve already done some interesting exercises, but now it’s time for a few more challenges.

### Challenge 5.1: Mapping is important

In this chapter, you learned how to implement different types of higher-order functions, and in the next chapter, you’ll see many more. A very important one is called `map`. This is a function that applies a given function `fn` of type `(A) -> B` to all the elements of a collection of items of type `A`, getting a collection of items of type `B`.

Can you implement the function `map` for the `Array<A>` type with the following signature?

``````fun <A, B> Array<A>.map(fn: (A) -> B): Array<B>
``````

When you run this code:

``````fun main() {
val square = { a: Int -> a * a }
val toString = { a: Int -> "This is \$a" }
arrayOf(1, 2, 3)
.map(square)
.forEach(::println)
arrayOf(1, 2, 3)
.map(toString)
.forEach(::println)
}
``````

You should get:

``````1
4
9
This is 1
This is 2
This is 3
``````

### Challenge 5.2: Prime number filtering

Write a higher-order function `all` returning a new array containing all the values in an `Array<T>` for which a given `Predicate1<T>` is true. You can find `Predicate1<T>`’s definition in Predicates.kt.

``````fun <T> Array<T>.all(predicate: Predicate1<T>) : Array<T>
``````

Then, use it to return all the positive prime values in `Array<Int>`. A number is prime if it’s not evenly divisible with any number other than 1 and itself.

## Key points

• A lambda expression is a function you can use as a value.
• A higher-order function accepts other functions as input parameters or provides other functions as return values.
• The declarative approach makes code more readable.
• Kotlin allows you to define functional interfaces, which are a handy way to define interfaces with a single abstract method that can be used as lambda expressions.
• Functional interfaces are also called SAM, which stands for single abstract method.
• A closure of a function is the set of all the variables the function can access, which have been defined outside its own body.
• A lambda function can modify its non-constant closures.
• Always consider using the `inline` keyword for higher-order functions, but double-check that the behavior is what you expect, especially in the context of non-local returns.
• The `noinline` and `crossinline` keywords are two additional options you have to control the flow of your program when using higher-order functions.

## Where to go from here?

Congratulations! In this chapter, you learned a lot about what higher-order functions are and how they can help you write your code in a more declarative way. Composition and higher-order functions are the essentials of functional programming. Right now, you’re just at the beginning. In the next chapter, you’ll be introduced to immutability and recursion: two important topics when using higher-order functions.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.