3 loops you should rewrite with Functional Programming in Swift

Luca Angeletti
5 min readJul 15, 2018

Writing Functional Programming code is all about describing the result you expect and to stop telling the computer step by step what it should do.

Basically, it’s a great way of writing declarative code instead of the low-level imperative code that we all have been writing for the last few decades.

In this article, we are going through three classic problems we are used to solving with for loops and we’ll see how using Functional Programming can make our code much:

  1. Easier to read
  2. More essential
  3. Safer

To write proper Functional Programming code, we are going to following these two rules:

  1. No mutable states (no class instances and no variables)
  2. No loops

Ready to start?!?

Filtering

Here we have an array of String(s) containing the names of some glorious starships. Our target is extracting only the names with lengths equal to seven.

This is how we typically solve the problem using Imperative Programming, right?

var ships = ["Enterprise", "Defiant", "Voyager", "Discovery"]
var result: [String] = []
for ship in ships {
if ship.count == 7 {
result.append(ship)
}
}
print(result) // ["Defiant", "Voyager"]

There are few things in this code we want to avoid:

  1. Variables
  2. Loops
  3. Imperative code

Let’s solve the problem using the “filter” method from Functional Programming

let ships = ["Enterprise", "Defiant", "Voyager", "Discovery"]
let result = ships.filter { $0.count == 7 }

How does it work? 🤔

As you can see, we removed all the variables and the code now looks more like plain English. Specifically reading the second line, we can instantaneously understand what the code does.

let result = ships.filter { $0.count == 7 }

It stores into result all the ships where the count of characters is seven.

What we don’t see is how the computer can achieve that. In fact, all the low-level steps are now gone, replaced by the filter invocation.

However, how does the filter work?

Filter is a Higher Order Function; precisely it is a method (function) that accepts another function (closure).

Here’s the closure:

{ $0.count == 7 }

Filter is going to apply that to each element of ships, and $0 represents the n-th element of ships.

In other words, Swift is going to run the following instructions:

"Enterprise".count == 7
"Defiant".count == 7
"Voyager".count == 7
"Discovery".count == 7

Each time the n-th expression is evaluated as true, the element is added to the result.

And since this is the result of the four evaluations:

"Enterprise".count == 7 // false
"Defiant".count == 7 // true
"Voyager".count == 7 // true
"Discovery".count == 7 // false

The final result will be

["Defiant", "Voyager"]

Mapping

Next problem, we have this struct

struct Person {
let name: String
let birthYear: Int
}

and this list of values.

let persons = [
Person(name: "Walter White", birthYear: 1959),
Person(name: "Jesse Pinkman", birthYear: 1984),
Person(name: "Skyler White", birthYear: 1970)
]

Now we want to create a new array containing only the names of the people stored in persons.

Here’s the traditional Imperative Programming code:

var names = [String]()
for person in persons {
names.append(person.name)
}
// names = ["Walter White", "Jesse Pinkman", "Skyler White"]

And here’s the Functional Programming code

let names = persons.map { $0.name }// names = ["Walter White", "Jesse Pinkman", "Skyler White"]

How does it work? 🤔

The “map” method allows you to transform a sequence into another one. You just need to provide the closure to transform the n-th element from the original sequence into an element of the destination. Map will apply the closure to each element of the source sequence to build the final result for you.

Reducing

Here is the last example. We have an array of Int(s), and we need to calculate the sum of all the values.

This is a typical example of how this problem is solved with Imperative Programming.

let numbers = [1, 2, 3]
var sum = 0
for num in numbers {
sum += num
}
print(sum) // 6

And this is how it can be solved using reduce from Functional Programming.

let numbers = [1, 2, 3]
let sum = numbers.reduce(0, +)

How does it work? 🤔

The reduce method can compress a sequence into a single value.

In this case, we are using it to compress an array of Int(s) into a single Int value.

  1. The first parameter of reduce is used to initialize the partial result.
  2. The second parameter is a closure, which is applied to combine the partial results and the n-th element of numbers.

Here’s how it works:

partialResult = 0 + 1 // 1
partialResult = 1 + 2 // 3
partialResult = 3 + 3 // 6

After the last iteration partialResult can be considered the final result and its value is six.

Wrap-up

This is just a sneak peak of what Functional Programming can do for your code.

As you have seen, each code snipped from Imperative Programming code has been reduced to a single line of Functional Programming code. Also, that single line is usually more readable because it uses a language closer to how our brain works.

I have been using Functional Programming since the first beta of Swift and hope you’ll enjoy it as much as I do. :)

--

--