Functional Programming in Kotlin: From A to Z — A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Functional Programming in Kotlin: From A to Z

Functional programming (FP) is a paradigm that treats computation as the evaluation of mathematical functions and avoids changing state and mutable data. Kotlin, being a multi-paradigm language, provides powerful tools for applying a functional approach without forcing you to abandon familiar OOP. In this article, we will break down the key concepts of FP in Kotlin: from pure functions and immutability to advanced techniques such as composition and monads.



1. Fundamentals of the Functional Approach: Pure Functions and Immutability

The foundation of FP is built on two principles: function purity and data immutability.

  • Pure function — a function whose result depends only on the passed arguments and which has no side effects (does not modify external variables, does not print to the console, does not access the database).
  • Immutability means that data cannot be changed after creation. Instead of modifying an existing object, a new copy with the desired changes is created.

Example of a pure and impure function in Kotlin:

// Impure function: has a side effect (console output)fun impureSum(a: Int, b: Int): Int {    println("Sum: ${a + b}") // side effect    return a + b}

// Pure function: only computationfun pureSum(a: Int, b: Int): Int = a + b

// Immutability: using val instead of vardata class User(val name: String, val age: Int) // val makes fields immutablefun main() { val user = User("Alice", 30) // user.age = 31 // Compilation error! val olderUser = user.copy(age = 31) // create a new copy}

Using val and data class with copy() is the standard way to maintain immutability in Kotlin.



2. Higher-Order Functions and Lambda Expressions

Kotlin supports functions as first-class objects. This means functions can be passed as arguments, returned from other functions, and stored in variables. Functions that take or return other functions are called higher-order functions.

Lambda expressions are a compact way to create anonymous functions. Syntax: { arguments -> body }.

// Higher-order function: takes a function (Int, Int) -> Intfun operateOnNumbers(a: Int, b: Int, operation: (Int, Int) -> Int): Int {    return operation(a, b)}

fun main() { // Lambda expressions val sum: (Int, Int) -> Int = { x, y -> x + y } val multiply: (Int, Int) -> Int = { x, y -> x * y }

println(operateOnNumbers(5, 3, sum)) // 8 println(operateOnNumbers(5, 3, multiply)) // 15

// Using a lambda "on the fly" println(operateOnNumbers(10, 2, { a, b -> a - b })) // 8

// If the lambda is the last argument, it can be moved outside the parentheses (trailing lambda) println(operateOnNumbers(10, 2) { a, b -> a / b }) // 5}

The Kotlin standard library heavily uses higher-order functions: map, filter, reduce for collections.

val numbers = listOf(1, 2, 3, 4, 5)val evenSquares = numbers    .filter { it % 2 == 0 } // {2, 4}    .map { it * it }        // {4, 16}println(evenSquares) // [4, 16]


3. Function Composition and Currying

Composition is the process of combining two or more functions to create a new function. Kotlin does not have a built-in composition operator like Haskell, but it is easy to implement manually or using extension functions.

// Composition of two functionsinfix fun  ((B) -> C).compose(f: (A) -> B): (A) -> C = { a -> this(f(a)) }

fun main() { val toInt: (String) -> Int = { it.toInt() } val square: (Int) -> Int = { it * it }

val squ

Blogs

Book Recommendations