Functional Programming in Swift: Basics and Examples

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 Swift: From Closures to Composition



Swift was originally designed as a multi-paradigm language. It supports object-oriented, protocol-oriented, and functional programming. The functional approach helps write more predictable, testable, and concurrency-safe code. In this article, we will break down the key concepts of functional programming in Swift with practical examples.



1. Pure Functions and Immutability



The foundation of the functional style is pure functions. Such a function always returns the same result for the same arguments and has no side effects (does not change external state).



// Impure function — modifies an external variablevar total = 0func addToTotal(_ value: Int) -> Int {    total += value    return total}

// Pure function — only computationfunc add(_ a: Int, _ b: Int) -> Int { return a + b}


Immutability is achieved through let and structures with value semantics. Instead of modifying an array, we create a new one:



let numbers = [1, 2, 3, 4, 5]// Instead of var and append:let newNumbers = numbers + [6] // [1, 2, 3, 4, 5, 6]


2. Closures as Building Blocks



Closures in Swift are anonymous functions that can capture variables from their surrounding context. They are "first-class citizens": they can be passed as parameters and returned from functions.



// Simple closurelet multiply: (Int, Int) -> Int = { $0 * $1 }let result = multiply(3, 4) // 12

// Closure with context capturevar counter = 0let increment = { counter += 1 }increment() // counter = 1increment() // counter = 2


Closures are actively used in higher-order methods such as sorted:



let names = ["Ivan", "Anna", "Boris", "Elena"]let sorted = names.sorted { $0.localizedStandardCompare($1) == .orderedAscending }print(sorted) // ["Anna", "Boris", "Elena", "Ivan"]


3. Higher-Order Methods: map, filter, reduce



These are the "workhorses" of the functional style in Swift. They allow processing collections without explicit loops and mutation.



map

Transforms each element of the collection:



let prices = [100, 200, 300]let withTax = prices.map { $0 * 1.2 }print(withTax) // [120.0, 240.0, 360.0]

// Real example: extracting names from an array of modelsstruct User { let name: String let age: Int}let users = [User(name: "Alexey", age: 30), User(name: "Maria", age: 25)]let userNames = users.map { $0.name }print(userNames) // ["Alexey", "Maria"]


filter

Selects elements based on a condition:



let numbers = [1, 2, 3, 4, 5, 6]let evenNumbers = numbers.filter { $0 % 2 == 0 }print(evenNumbers) // [2, 4, 6]

// Filtering users older than 18let adults = users.filter { $0.age >= 18 }


reduce

Reduces the collection to a single value:



let sum = numbers.reduce(0, +) // 21// Building a string from an arraylet words = ["Functional", "programming", "Swift"]let sentence = words.reduce("") { $0.isEmpty ? $1 : $0 + " " + $1 }print(sentence) // "Functional programming Swift"


Combining Methods

The most interesting part is method chaining:



let transactions = [250, -50, 100, -200, 300, -100]let balance = transactions    .filter { $0 > 0 }          // only income    .map { $0 * 0.87 }          // subtract 13% tax    .reduce(0, +)               // sum upprint(balance) // 565.5


4. Function Composition and Currying



Composition allows combining several functions into one. Swift does not have a built-in composition operator

Blogs

Book Recommendations