Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Swift Functional Programming

You're reading from   Swift Functional Programming Ease the creation, testing, and maintenance of Swift codes

Arrow left icon
Product type Paperback
Published in Apr 2017
Publisher Packt
ISBN-13 9781787284500
Length 316 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Dr. Fatih Nayebi Dr. Fatih Nayebi
Author Profile Icon Dr. Fatih Nayebi
Dr. Fatih Nayebi
Arrow right icon
View More author details
Toc

Table of Contents (12) Chapters Close

Preface 1. Getting Started with Functional Programming in Swift 2. Functions and Closures FREE CHAPTER 3. Types and Type Casting 4. Enumerations and Pattern Matching 5. Generics and Associated Type Protocols 6. Map, Filter, and Reduce 7. Dealing with Optionals 8. Functional Data Structures 9. Importance of Immutability 10. Best of Both Worlds and Combining FP Paradigms with OOP 11. Case Study - Developing an iOS Application with FP and OOP Paradigms

What is FP?

We know FP matters, but what is it really? There are a lot of discussions related to FP superiority and different definitions of it, but simply, it is a style of programming that models computations as the evaluation of expressions or declarations. FP is a declarative programming style, as opposed to OOP, which is categorized as imperative programming.

Theoretically, FP employs the concepts of category theory, which is a branch of mathematics. It is not necessary to know the category theory to be able to program functionally, but studying it will help to grasp some of the more advanced concepts, such as Functors, Applicative Functors, and Monads. We will get into category theory and its relationship with FP later, so for now, we are not going to talk math and we will scratch the surface of FP pragmatically.

Let's start with an example to understand the differences between imperative and declarative programming styles. The following example gives two different approaches to array-element multiplication:

let numbers = [9, 29, 19, 79] 

// Imperative example
var tripledNumbers: [Int] = []
for number in numbers {
tripledNumbers.append(number * 3)
}
print(tripledNumbers)

// Declarative example
let tripledIntNumbers = numbers.map({ number in number * 3 })
print(tripledIntNumbers)

In the imperative example, we create a mutable array of integers. Then, we give a command to go through all items in the array, multiply each item by 3, and add it to our mutable array. Basically, we order the compiler to follow specific steps. As it is written in an imperative style, when we read it, we will need to trace and follow the same steps, like a compiler, which is not very intuitive.

In the declarative example, we declare how numbers should be mapped, multiplying each number by 3. It may not look that intuitive right away if we do not know the map function and closures, but for now we need to understand the differences between commanding and declaration. This example may not be enough to grasp it. Also, understanding a concept is one thing and applying it is another. That is why we will have more examples in upcoming sections and chapters. In fact, everything in this book will be written declaratively, so we will utilize the concept intuitively.

In FP, functions are the fundamental building blocks, so programs are structured by functions. In OOP, programs are composed of classes and objects. This is a fundamental difference because, in OOP, statements can mutate the state of objects when executed, as opposed to FP, which avoids using mutable states.

FP promises that avoiding mutable states makes it easier to test, read, and understand the code. Although it is a well-known fact that state management is hard and error-prone, it is not easy to avoid mutable states in some cases, such as cocoa development and file and database operations. For now, we consider traditional OOP and FP, and we will get into the comparison and combination of different paradigms in an upcoming chapter.

FP requires functions to be first class. First-class functions are going to be treated like any other values, and can be passed to other functions or returned as a result of a function.

FP requires functions to be able to be formed as higher-order functions that take other functions as their arguments. Higher-order functions can be used to refactor code, reduce the amount of repetition, and to implement domain-specific languages (DSL).

DSLs are languages that are specialized for a particular application domain. Domain-Specific Languages, a book by Martin Fowler, is a great reference for the curious. For more curious readers, declarative Auto Layout DSLs for Swift such as SnapKit and Carthography and a talk given by Rahul Malik at Functional Swift conference on writing domain specific languages (https://github.com/rahul-malik/writing-dsls) are great resources.

FP requires functions to be pure so they do not depend on any data outside of themselves and do not change any data outside of themselves. Pure functions provide the same result each time they are executed. This property of pure functions is called referential transparency, and makes it possible to conduct equational reasoning on the code.

Equational reasoning is a way to reason about our code. It enables us to replace code blocks with others without worrying about evaluation order or state. In OOP, generally, the value of a code block depends on object context or state. Having a context and depending on state prevents replacing a code block by another, and therefore makes it impossible to conduct equational reasoning.

First-class, higher-order, and pure functions empower us to compose our applications with functions instead of using classes and objects as building blocks.

In FP, expressions can be evaluated lazily. For instance, in the following code example, only the first element in the array is evaluated:

let oneToFour = [1, 2, 3, 4] 
let firstNumber = oneToFour.lazy.map({ $0 * 3}).first!
print(firstNumber) // The result is going to be 3

The lazy keyword is used to get a lazy version of the collection. lazy is declared in Swift's Standard Library as a view onto the collection that provides lazy implementations of normally eager operations, such as map and filter. In this example, only the first item in the array is multiplied by 3 and the rest of the items are not mapped.

At this point, we should have a very broad view of FP concepts. To be able to get into the detail of these concepts, we will need to cover some of the Swift language basics, which are provided in the following section.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime