Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Functions as First-Class Citizens | Control Flow and Collections
Android Development with Kotlin
course content

Course Content

Android Development with Kotlin

Android Development with Kotlin

1. Kotlin Basics
2. Control Flow and Collections
3. Object-Oriented Programming in Kotlin

Functions as First-Class Citizens

Now I'm going to tell you about some very interesting things in Kotlin.

Kotlin is a functional programming language, which means it uses higher-order functions. But what are higher-order functions?

Higher-Order Functions.

Higher-order functions are functions that take other functions as arguments or return functions.

Note

I hope you haven't forgotten what functions are and how to use them?

Let’s look at how we can pass a function as an argument to another function:

kt

Main

copy
1234567891011121314151617181920
fun main() { val result1 = applyOperation(5, ::square) // passing the square function val result2 = applyOperation(5, ::increment) // passing the increment function println("Square of 5: $result1") println("Increment of 5: $result2") } fun applyOperation(x: Int, operation: (Int) -> Int): Int { // This is the higher-order function // This function accepts and returns functions return operation(x) } fun square(n: Int): Int { return n * n } fun increment(n: Int): Int { return n + 1 }

Let's break down each of these functions to understand how they work.

With the square and increment functions, it should be clear how they work. The square function simply takes an integer value and returns its square. The increment function takes an integer value and returns that value incremented by 1.

The applyOperation function is where things get more interesting.

First, this function takes two arguments: the first is an integer value to which the operation will be applied, and the second is the operation itself, which is a function.

The illustration below will explain in more detail how such an internal function is written:

We can conclude that using a simple lambda expression, we can specify the parameters a function will accept and the type of data it will return. This is necessary for a higher-order function to accept only a specific type of function.

Otherwise, there could be errors with the return data type when the higher-order function tries to pass the wrong data types to the inner function.

Now, let's break down how calling such a function and passing a parameter looks.

As you can see, we use the syntax applyOperation(5, ::square) to calculate the square of 5.

To pass an appropriate function as a parameter, we use double colons:

This can have many useful applications. For instance, the code above greatly enhances code readability and makes it much more organized.

Returning Functions

We can also return specific functions from functions, but this will look fairly straightforward:

kt

Main

copy
123456789101112131415
//Creation a multiplier function fun createMultiplier(factor: Int): (Int) -> Int { // returning new function from the function return fun(n: Int): Int { return n * factor } } fun main() { val multiplyBy2: (Int) -> Int = createMultiplier(2) val multiplyBy3: (Int) -> Int = createMultiplier(3) println(multiplyBy2(5)) println(multiplyBy3(5)) }

Function Signature:

  • fun createMultiplier(factor: Int) — This defines a function named createMultiplier that takes a single argument factor of type Int;

Return Type:

  • : (Int) -> Int — This indicates that createMultiplier returns a function that takes an Int as an argument and returns an Int;

Function Body:

  • return fun(n: Int): Int { return n * factor } — This returns an anonymous function that takes an integer n and returns the result of n multiplied by factor;

Calling createMultiplier:

  • val multiplyBy2 = createMultiplier(2) — This calls createMultiplier with the argument 2 and assigns the returned function to the variable multiplyBy2. The returned function will multiply any given number by 2;
  • val multiplyBy3 = createMultiplier(3) — Similarly, this calls createMultiplier with 3, creating a function assigned to multiplyBy3 that multiplies any given number by 3.

You can also see that we specify the data type for the variable that holds the function using a lambda expression, just as we do with functions.

This way, we can store functions in variables (known as anonymous functions), use them inside other functions, and return them as values. There's a lot you can do with functions in Kotlin, and with experience, you'll better understand how it all works!

What is a higher-order function in Kotlin?

Select the correct answer

Everything was clear?

Section 2. Chapter 6
We're sorry to hear that something went wrong. What happened?
some-alt