Chapters

Hide chapters

Kotlin Apprentice

Third Edition · Android 11 · Kotlin 1.4 · IntelliJ IDEA 2020.3

Before You Begin

Section 0: 4 chapters
Show chapters Hide chapters

Section III: Building Your Own Types

Section 3: 8 chapters
Show chapters Hide chapters

Section IV: Intermediate Topics

Section 4: 9 chapters
Show chapters Hide chapters

21. Functional Programming
Written by Irina Galata

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

The evolution of programming as an engineering discipline includes improvement of languages and tools. There are also different fundamental approaches you can use to develop your programs, often called paradigms. There are various programming paradigms, but don’t be intimidated, since all of them have strengths and weaknesses.

The more comfortable you become with the different approaches, the easier it will be able to apply them. Plus, you already know at least one of them: object-oriented programming aka OOP. In this chapter, you’ll get acquainted with another type of programming — functional programming — and learn its technical details.

What is functional programming?

You may remember that a key feature of OOP is that classes and their instances contain properties and methods. Functional programming is instead based around the use of functions, which ideally don’t have side effects.

A side effect is any change to the state of a system. A simple example of a side effect is printing something to the screen. Another is changing the value of the property of an object. Side effects are typically rampant in OOP, as class instances send messages back and forth to one another and change their internal state.

Another key feature of functional programming making functions first-class citizens of the language, as you’ll see in a future section.

Most functional programming languages also rely on a concept called referential transparency. This term effectively means that given the same input, a function will always return the same output. When a function has this property it is called a pure function.

Functions in functional programming languages are more like their mathematical namesake functions than typical functions in non-functional programming approaches.

Unlike versions of Java prior to Java 8, Kotlin allows you to use both the OOP and functional approaches to building software, either separately or by combining them to make your code more efficient and flexible. In this chapter, you’ll see an example of the combination of the ideas of OOP and functional programming.

Getting started

Before diving into using functional programming, you’ll setup a system that will let you explore the details. Open up the starter project and keep reading.

First-class and higher-order functions

One of the main ideas of functional programming is first-class functions. This means that you can operate with functions in the same ways you can other elements of the language — you can pass functions as arguments to other functions, return functions from functions, and assign functions to a variable. Functions that receive a function as a parameter or return functions are called higher-order functions.

Function types

To declare a function which receives a function parameter or returns another function, it’s necessary to know how to specify a function type.

Passing a function as an argument

Update beginBattle() to receive another function as a parameter, which will be executed when the battle is finished. That way, you’ll know exactly which robot has won:

Returning functions

Similar to passing functions as arguments, you can return a function from another function, as in the following code:

Lambdas

As you learned about in Chapter 10, a lambda is a function literal, which can be invoked, passed as an argument or returned just like ordinary functions. In this chapter, you’ll learn a bit more about lambdas in the context of functional programming.

How do lambdas work?

When you defined the onBattleEnded lambda, it was compiled to the equivalent of the following Java code:

Closures

Lambas (as well as local functions) act as closures, which means that they can access and modify variables defined outside of their own scope. Unlike Java, variables declared in the outer scope can be modified within the closure.

Extension functions

You learned about extension methods on classes in Chapter 14. Let’s look at them again from the perspective of functional programming.

Lambdas with receivers

Just as you can specify a receiver for an extension function, you can do so for a lambda as well.

Anonymous functions

Anonymous functions are more or less the same as ordinary ones, but they don’t have a name. To invoke them, you need to assign them to a variable or pass them as an argument to another function. Consider the following snippet of code:

Returning from lambdas

If you use a regular return expression inside a lambda, you’ll return to the call site of the outer function. That is, the return in the lambda also returns from the outer function.

Inline functions

Remember that, for each lambda that you create to pass to another function, the Kotlin compiler generates an appropriate class extending FunctionN. In some cases, that might not be a good solution, especially when you do it multiple times, as this will increase memory usage and have a performance impact on your application.

Undayluc kadlexkupze uxdokh kzor ocgibadv if ucqevliterecv. Ugtotoyv mufjm tewl jop yejjkoudx lujl wotemaxehv iw gotggooqoy zgyol.
Ubsafren foznolzidwu oyvavd pkis ohvoxisn uz ulkivpetexifm. Ugdaserq tedhv gowq luq qarhvieqk zorx honifihapw aw heynhooxaf tvceb.

noinline

If you don’t want some of the lambda parameters to be inlined along with the higher-order function, you can mark the lambda as noinline. A FunctionN instance will still be generated for noinline lambda:

crossinline

The crossinline keyword is used to mark a lambda parameter which shouldn’t allow a non-local return (i.e., return without a label). This is useful when a function, which receives a lambda, will call it inside another lambda. In this case, it’s not allowed to return from such a lambda. Take a look at the example below:

Yer'p afwevi 'guwr' yape: ay hob sojvois dut-dirur wuzoygp. Edk 'jzonvevkude' ketoveam ta jexafacaz tofhitojeom 'lunw'
Ziv'm ewwilu 'dumr' goha: uh zol ludceis yig-yexaf kisolzl. Aqr 'cgevqiplufa' zekahaaz ku legubuyew wijfawiwaop 'nelk'

'nuqabk' ir mer eqkukom vove
'sivemf' op lak afxuvuf rowu

Tail recursive functions

The last expression in a function is called the tail call. If, in some cases, the function gets called again in the tail call expression, this function is called tail-recursive. In Kotlin, you can mark such functions as tailrec, and the Kotlin complier will replace the recursion by an appropriate loop for the sake of performance optimization. This will ensure that your recursive code does not cause a stack overflow.

Collections standard library

The use of standard library functions on collections that you saw in Chapter 10 are further examples of functional programming. The Kotlin standard library offers you a huge amount of useful functions for collection processing.

Infix notation

If a function is a member function or an extension function and receives only one argument, you can mark it with the infix keyword. That way you can invoke it without a dot and parentheses.

Sequences

In Kotlin, you can use Sequence to create a lazily evaluated collection so that you can operate on collections of unknown size, which can be potentially infinite.

Challenges

Key points

Where to go from here?

Functional programming opens a world of possibilities, which are difficult to cover entirely in a single chapter. But to deepen your knowledge after understanding the basics, you can move on to more advanced concepts, such as function composition, Either, Option, Try, and more.

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.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now