Higher Order Functions in Swift – An Introduction

Updated on May 1st, 2021

⏱ Reading Time: 4 mins

Higher order functions in Swift; a term you have probably heard of, maybe you have used some of them or seen them being used, but do you really know what a higher order function is?

This post is dedicated on explaining what a higher order function is, and how it differs from normal functions. Here not only you will find out the answer to that, but also you will see how you can implement your own custom higher order functions. Follow-up posts will demonstrate various commonly used and well-known built-in higher order functions in Swift.

There is just one think to understand when it comes to higher order functions. They are functions that accept other functions as arguments, or they return a function as their results. The same goes for closures as well; after all, a closure is a nameless function. So, once again…

a higher order function is a function that accepts other functions or closures as arguments, or returns a function or a closure as its result.

That sounds nice, but what does it really mean in practice? To get a taste, open a playground in Xcode and follow along. No matter if it’s likely or not to create your own higher order functions, the examples coming next are going to help you fully understand what those functions are.

To get started, suppose that we have the following enumeration that indicates the four basic mathematical operations:

Now, say that we want to implement a function that will be doing one thing only:

Based on a MathOperation value we will provide it with, it will be returning a function that will be performing the actual math operation between two operands.

For simplicity, let’s agree that we’ll be dealing with Double values only. The definition of that function will be this:

See the return value; (Double, Double) -> Double?. It’s the declaration of a function without a name. In an exactly similar fashion we declare closures, don’t we? The parameter values match to two operands of Double type, while the result is also a Double value. It’s marked with the ? symbol as an optional, so in case of a division with zero the program won’t crash.

Let’s add some content to the above function now, starting with the implementation of the four functions that will be calculating the result for each operation. Note that all new functions are defined inside the math(operation:) function -yes, we can do that-:

Next, we will return the proper function from math(operation:), depending on the operation parameter value:

The above is a higher order function! It returns another function as its result.

We can now use it as follows:

The first time math(operation:) is called, it returns the addition(_:_:) function. The second time it returns the multiplication(_:_:) function, as specified by the provided argument. Print commands will show the values 16.0 and 57.75 respectively, after performing the actual math operations between the two given numbers.

Let’s implement now a function that accepts another function as argument, instead of returning one as its result. I will begin with the same four math functions that perform the basic calculations:

With the above as granted, here’s the definition of the new function:

The first two parameter values are the two operands that will be used to calculate a result. The third parameter value, which is the most interesting part here, is a function; it expects two arguments of Double type, returning an optional Double result.

Inside its body there will be a single line only that will be calling the operation function passing the first two parameter values as arguments:

The actual function that operation will be matching to, depends on the one that we will provide as argument. For example, to perform a multiplication we can call the above with the two values we want to multiply, plus the function that performs the multiplication:

To perform a subtraction:

In both last two examples we provided a named function as argument. However, that’s not mandatory. We can use closures instead. The following example demonstrates how to pass a closure as an argument to the demo higher order function. In its body we calculate and return the average of the two given values:

Demo code in Xcode playground

Now you know what we mean with the higher order functions term, and what their difference is comparing to normal functions, called first order functions. Even though the presented examples were quite simplistic, they are still good enough in order to help you get your head around that topic.

In the following posts I am going to showcase how certain built-in higher order functions provided in Swift work, and what you can do with them. I’ll start will the map, compactMap and flatMap functions, and then I’ll proceed to a few others. So, stay tuned!

The next post about map, compactMap, and flatMap higher order functions is available here.

Stay Up To Date

Subscribe to my newsletter and get notifiied instantly when I post something new on SerialCoder.dev.

    We respect your privacy. Unsubscribe at any time.