Swift isn't a functional programming language, but you can use functional techniques in the code you write. Why is that? Swift has a number of functional features. For example, Swift has first-class functions and that opens up some interesting possibilities. In this post, you learn about higher-order functions and how you can use them in your projects.

What Is a Higher-Order Function?

Let's take it one step further and talk about higher-order functions. Don't let yourself be thrown off by the term higher-order function. Like the term pure function, the idea is simple. A higher-order function accepts one or more functions as arguments or it returns a function. It can also do both. Let me show you an example to make sure you understand the concept.

I bet you are familiar with Swift's map(_:) function. Take a look at this example. We define a variable, fruits, of type [String]. The array of strings contains three elements. I would like to make each string in the array uppercase. The map(_:) function is perfect to carry out this task. We call map(_:) on fruits, passing in a closure. The map(_:) function invokes the closure for each element in the array, passing the element to the closure as an argument. We invoke uppercased() on the String object and implicitly return it from the closure.

import Foundation

let fruits = [
    "apple",
    "orange",
    "cherry"
]

fruits.map { (string) -> String in
    string.uppercased()
}

The result of the map(_:) function is an array of strings. The array of strings that is stored in fruits is not modified. We can simplify the implementation by using shorthand argument syntax and by leveraging type inference.

import Foundation

let fruits = [
    "apple",
    "orange",
    "cherry"
]

fruits.map { $0.uppercased() }

The map(_:) function is a higher-order function because it accepts a function as an argument. In the example, we pass a closure to the map(_:) function, but it can be a function with a name. Take a look at this example.

import Foundation

let fruits = [
    "apple",
    "orange",
    "cherry"
]

func uppercase(_ string: String) -> String {
    string.uppercased()
}

fruits.map(uppercase)

We define a function, uppercase(_:), that accepts an argument of type String and returns a String object. The uppercase(_:) function is a pure function. The signature of the uppercase(_:) function matches what the map(_:) function expects. We can pass the uppercase(_:) function as an argument to the map(_:) function. The result is identical.