An Introduction to Functional Programming in Swift

In this tutorial you’ll learn, step by step, how to get started with functional programming and how to write declarative, rather than imperative, code. By Warren Burton.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Solving the Problem with the Imperative Approach

Think about how you would solve this problem with an imperative algorithm. Have a try at implementing your own solution to the problem.

Your solution will likely be similar to:

var ridesOfInterest: [Ride] = []
for ride in parkRides where ride.waitTime < 20 {
  for category in ride.categories where category == .family {
    ridesOfInterest.append(ride)
    break
  }
}

let sortedRidesOfInterest1 = ridesOfInterest.quickSorted()
print(sortedRidesOfInterest1)

Add this to your playground and execute it. You should see that Mountain Railroad, Crazy Funhouse and Grand Carousel are the best ride choices and that the list is in order of increasing wait time.

As written, the imperative code is fine, but a quick glance does not give a clear, immediate idea of what it’s doing. You have to pause to look at the algorithm in detail to grasp it. Would the code be easy to understand when you return to do maintenance six months later, or if you’re handing it off to a new developer?

Add this test to compare an FP approach to your imperative solution:

func testSortedRidesOfInterest(_ rides: [Ride]) {
  let names = rides.map { $0.name }.sorted(by: <)
  let expected = ["Crazy Funhouse",
                  "Grand Carousel",
                  "Mountain Railroad"]
  assert(names == expected)
  print("✅ test rides of interest = PASS\n-")
}

testSortedRidesOfInterest(sortedRidesOfInterest1)

Solving the Problem with a Functional Approach

You can make your code a lot more self-explanatory with an FP solution. Add the following code to your playground:

let sortedRidesOfInterest2 = parkRides
    .filter { $0.categories.contains(.family) && $0.waitTime < 20 }
    .sorted(by: <)

Verify that this line of code produces the same output as the imperative code by adding:

testSortedRidesOfInterest(sortedRidesOfInterest2)

In one line of code, you’ve told Swift what to calculate. You want to filter your parkRides to .family rides with wait times less than 20 minutes and then sort them. That cleanly solves the problem stated above.

The resulting code is declarative, meaning it’s self-explanatory and reads like the problem statement it solves.

This is different from imperative code, which reads like the steps the computer has to take to solve the problem statement.

The When and Why of Functional Programming

Swift is not purely a functional language, but it does combine multiple programming paradigms to give you flexibility for app development.

A great place to start working with FP techniques is in your Model layer and anywhere that your app’s business logic appears. You’ve seen how easy it is to create discrete tests for that logic.

For user interfaces, it’s less clear to see where you’ll want to use FP techniques. Reactive programming is an example of an FP-like approach for UI development. For example, RxSwift is a reactive library for iOS and macOS programming.

By taking a functional, declarative approach, your code becomes more concise and clear. Plus, your code will be easier to test when it’s isolated into modular functions which are free from side effects.

When you want to maximize the full potential of your multi-core CPU, minimizing side effects and issues from concurrency is important. FP is a great tool to have in your skill set for those kind of problems.

Where to Go From Here?

You can download the complete playground with all the code in this tutorial from the Download Materials button at the top or bottom of the tutorial.

While you’ve reviewed many of the important concepts of FP in this tutorial, you’ve only scratched the surface of what FP is and what it can do. Once you have some experience with these basic FP concepts, take the plunge into the heart of FP by exploring:

  • Monads, Endofunctors and Category Theory.
  • Programming languages where FP is the focus, such as Haskell and Clojure.

You’ll get great insights into various aspects of Swift by studying these. You might be able to do things you never dreamed possible with your new-found knowledge.

You can also check out:

If you have any questions or comments about this tutorial, come and join the discussion below!