Swift: Functional Paradigm

When Swift was introduced, it introduced not just a new programming language, but a number of new techniques. One of the most powerful Swift language feature is the ability to write code in more functional style. I took some time to learn functional programming at the end of 2015 so I can write better Swift code. Although Swift can be written with functional programming in mind, Swift probably can not be a full fledged functional language in iOS development because it will, most of the time, have side effects.

Immutability

Swift’s immutability is terrible according to some of the developers in the community. This is because some of Swift’s immutable state can be changed. This seems contradictory to what immutable means but in functional programming, rather than mutating the state of objects, we simply return a new object with the changes we want. So, instead of thinking changes as mutations, think of them as creating and returning a new object. Take note that properties of an immutable class can be changed. According to the Swift Programming Language, the properties of constant structs are constants but constant classes can have mutable properties.
class SomeClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}
The class property name is a variable that is initialised when init is called.
let theClass = SomeClass(name: "ThisClass")
print(theClass.name) // ThisClass
We then create a constant property called theClass initialised with the name ThisClass. Now this is the good part…
theClass.name = "SomeClass"
print(theClass.name) // SomeClass
What just happened?
Constant class, changeable property. Let’s then create a struct…
struct SomeStruct {
    var name: String
    init(name: String) {
        self.name = name
    }
}
The struct property name is a variable that is initialised when init is called.
let theStruct = SomeStruct(name: "ThisStruct")
theStruct.name = "SomeStruct"
Working with struct on the other hand returns an error Cannot assign to property: 'theStruct' is a 'let' constant. Constant struct, unchangeable property.

Higher-order function

All other functions are first-order functions. Other programmers already used higher-order functions without them knowing by returning a function as result. With Swift, however, you can use functions as function arguments.
func twice(f: ([Int] -> Int), xs: [Int]) -> Int {
    return f(xs) * 2
}

func sum(xs: [Int]) -> Int {
    return xs.reduce(0, combine: +)
}

twice(sum, xs: [1,2,3,4,5])
What we did here is we created a function called twice that accepts two arguments f and xs, f is a function and xs is a list of integer and returns an integer as a result, and another function called sum that accepts a list of integer called xs and returns an integer as a result. sum will take the given list of integer and sum all numbers. twice is self explanatory, it doubles the value of the given function and argument. If you look closely at f‘s type, [Int] -> Int, this means that twice accepts a function that accepts a list of number and returns an integer. Making sum as twice‘s first argument value became possible because sum conforms to the argument’s type. reduce is another form of a higher-order function. The reduce function solves the problem of combining the elements of the list to a single value. In the code above, we used the + (plus) operator (many programming languages uses + as an addition operator) as the function to combine and initial value of 0. Our code should produce 30 (1 + 2 + 3 + 4 + 5) * 2.

Pure functions

In functional programming, when talking about functions, it means a pure function than the regular function i.e. mathematical functions. This function doesn’t have any side-effects, doesn’t affect any other parts of the program or that can be affected by any other part of the program. Because the function is completely isolated and must always evaluate the same result given the same argument values, it is very testable; the code itself is reusable that it can be composed to form more complex functions. An example of a pure function written in swift:
func sq(n: Int) -> Int {
    return n * n
}

print("Square root of 5 is: \(sq(5))") // Square root of 5 is: 25
In addition, functions that access database, local file system, or accepting any input and/or output are also considered to be impure. Impure functions are a common thing, and sometimes very visible (especially in C where many developers use impure functions), when making a function that can modify the input itself. An example in C:
void square(int *n);
int main()
{
    int n = 5;
    square(&n);
    printf("n: %d", n); // n: 25

    return 0;
}

void square(int *n) {
    *n = *n * *n;
}
Similar declaration in Swift:
func sq(inout n: Int) {
    n = n * n
}

var n = 5
sq(&n)

print("Square root of 5 is: \(n)") // Square root of 5 is: 25

Recursion

A function that calls itself is a recursive function. Recursive functions usually have less code and are more elegant than their iterative counterpart. It is better to use if the problem is recursive in nature. Let’s take factorial as an example since it is recursive in nature:
func factorial(n: Int) -> Int {
    guard n > 1 else {
        return 1
    }
    return n * factorial(n - 1)
}
print(factorial(5)) // 120
Calculating factorial of a number using our given value of 5 works as
factorial(5) = factorial(5) * factorial(4) * factorial(3) * factorial(2) * factorial(1)

Currying

There’s a chance you already heard or read about currying inside the Swift community who have a more functional-minded thinking. Currying is a feature found in most modern programming languages. It translates a single function with multiple arguments into a series of functions each with one argument.
func add(n: Int) -> Int -> Int {
    return { m in
        n + m
    }
}
print(add(10)(10))

Next Step

If you haven’t wrote a function that utilises any of the concepts above, then, congratulations! πŸŽŠπŸŽ‰ To actually see the functional paradigm in Swift work, we will write a simple program that will utilise some functional paradigm.

Luhn Algorithm

The Luhn algorithm or Luhn formula is a simple checksum formula used to validate a variety of identification numbers, including but not limited to credit card validation. So a while back I wrote about functional programming – what is it and it’s concepts. It was inspired by the course Introduction to Functional Programming. In that course there’s an exam to create a credit card validator the reason we will use it in Swift in a Swift way. To get started, first we need the logic of checking a credit card number if valid or not. Here’s the requirements, in the form of wikipedia’s description of the algorithm:
  1. From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if the product of this doubling operation is greater than 9 (e.g., 8 Γ— 2 = 16), then sum the digits of the products (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9) or alternatively subtract 9 from the product (e.g., 16: 16 – 9 = 7, 18: 18 – 9 = 9).
  2. Take the sum of all the digits.
  3. If the total modulo 10 is equal to 0 (if the total ends in zero) then the number is valid according to the Luhn formula; else it is not valid.
The logic of our program will be:
  1. Convert an Int to an array of Int
  2. Reverse the result of number 1
  3. Doubling the value of every second digit from the left (left since we reversed the sequence)
  4. Sum the digits of the result of number 3 while making sure anything above 9 will be separated
  5. Check if multiple of 10
extension Int {
    func toDigits() -> [Int] { // 1
        guard self > 9 else {
            return [self]
        }
        var a = (self / 10).toDigits() // power of recursion
        a.append(self % 10)
        return a
    }

    func isMultipleOf(n: Int) -> Bool { // 5
        return self % n == 0
    }

    func isValid() -> Bool {
        return Array(self.toDigits().reverse()) // 2
            .doubleSecond()
            .sum()
            .isMultipleOf(10)
    }
}

extension SequenceType where Generator.Element == Int {
    func doubleSecond() -> [Generator.Element] { // 3
        return self.enumerate().map { (i, e) in
            return (i % 2 != 0) ? (e * 2) : e
        }
    }

    func sum() -> Generator.Element { // 4
        return self.flatMap{ $0.toDigits() }.reduce(0, combine: +)
    }
}
4716347184862961.isValid() // true
And that’s it, we now have a working copy of a credit card validator in Swift using some functional programming techniques. Congratulations, again! πŸŽŠπŸŽ‰ First function of the Int extension is toDigits(), it extends the Int type that will convert an Int to an array of Int. First code is guard to check if the value is greater than 9, if not then return self inside an array. After that, it uses the power of recursion by splitting the value then divide by 10 until the value is less than 10. Second function of the Int extension is isMultipleOf(), it extends the Int type that will check if the value is divisible by 10. Third function of the Int extension is isValid(), it checks the credit card number if valid by using all functions we wrote. Next we wrote an extension of SequenceType that will accept an element of type Int. First function of the extension is doubleSecond() that will double the value by enumerating all values and mapping it by selecting every second digit. Second function of the SequenceType extension and the last function of our little program is sum(), it will sum up the value of all digits.
Angelo Villegas is an iOS Software Engineer from Manila. Building native iOS apps using Xcode, Objective-C and Swift, contribution to the open-source community and writing articles on AngeloVillegas.com