Functional Programming in Swift 2.0

What?

In this post I will talk about functional programming in Swift 2.0. Grab the latest release of Xcode 7 before trying out any of the following code because they might not compile on Swift 1.2.

For me, functional programming means a lot of things amongst which the followings stand out:

  • Immutability (avoiding having variables with changing states, think let in Swift)
  • Expectancy (knowing that a function does something, regardless of the environment under which it is running)
  • Functions (that accept functions as their parameters, and can return functions)

Here is an example:

  func doSoemthing(f: Int -> String) -> String -> Int{
    return {(s: String) in
      Int(f(10))!
    }
  }

This is a function that takes in a function called f (f has an Int argument and returns a String). As a return value, doSomething returns a function, let’s called it z (z takes in a String, and returns an Int). If this is giving you headache, then I’m doing my job right.

map()

The map() function can be applied on collection types and sequence types (SequenceType). This function takes in a collection, and for every item in that array, calls a function and passes the items inside the collection to the function. That function can in turn, for every item in the collection, return anything.

Let’s say that you want to convert an array of integers to string. You can do it in the conventional way:

    for i in 0..<10{
      let s = String(i)
      print(s)
    }

Or you could do it in the functional way:

    [0..<10].map{
      String($0)
    }

Now, map can be used to convert anything, to anything. This is really powerful. It can take an array of functions, and convert them to an array of another type of functions. Here is an example:

    typealias myFunc = Int -> String
    typealias yourFunc = String -> Int
    
    let f1: myFunc = {
      return String($0)
    }
    
    let f2: myFunc = {
      return String($0 + 100)
    }
    
    [f1, f2].map{(inputFunc: myFunc) -> yourFunc in
      let f: yourFunc = {
        Int(inputFunc(Int($0)!))!
      }
      return f
    }

This isn’t a common case but it is doable and it’s best to know about it. It’s best to know that anything can be mapped to anything, including functions to functions. Let’s look at another example. We have x number of functions that take a string and return a string. They do some operation on the incoming argument and return the results:

    typealias strFunc = String -> String
    
    let toUpperCase: strFunc = {
      $0.uppercaseString
    }
    
    let appendZero: strFunc = {
      $0 + "0"
    }

I can now have a string and call these functions one by one on the string:

    let str = "Vandad"
    
    print([toUpperCase, appendZero].map{
      $0(str)
    })

I would then get this as the result printed to the console:

[VANDAD, Vandad0]

filter()

The filter function also works on sequence types and collections. This is a function that can be called on a collection and passes the items in that collection one by one to a function that we will write. Our function has to return true or false for every item in the collection, filtering it out basically. Let’s say that you want to find inside an array all integers that are larger than 5:

    print(Array(0..<10).filter{       $0>5
    })

Or let’s say that you want to find all even numbers inside an array:

Array(0..<10).filter{$0 % 2 == 0}

Note that you can also use stride to do this:

stride(from: 0, through: 10, by: 2)

reduce()

This function can be called on a collection. It takes in an initial value, and takes in a function as a parameter. Your function will then take in an item from the collection, and the initial value, and has to return the same data type as the initial value. Let’s have a look at an example.

Let’s say that you have an array of strings and an array of functions. These functions take in a string, do something with it, and return a string:

    typealias strFunc = String -> String
    
    let toUpperCase: strFunc = {
      $0.uppercaseString
    }
    
    let appendZero: strFunc = {
      $0 + "0"
    }
    
    let prependZero: strFunc = {
      "0" + $0
    }

So I want to call these 3 functions, to all my strings, and get the results. My strings are:

    let strings = ["Vandad", "Aftonbladet"]

What I expect to get is an array with the first item equal to “0VANDAD0” and the next item as “0AFTONBLADET0”:

    let result = [toUpperCase, appendZero, prependZero].reduce(strings) { (strs: [String], thisFunc: strFunc) -> [String] in
      strs.map(thisFunc)
    }

Thanks to Swift’s intelligent compiler, I can get rid of a lot of boilerplate code and rely on the compiler to find out the datatypes:

    let result = [toUpperCase, appendZero, prependZero].reduce(strings) {
      $0.map($1)
    }

Final thoughts

Of course functional programming isn’t just about these 3 functions but these 3 are a good place to start.

/glhf


A Holistic View on Developer Productivity

What does developer productivity mean, really? Is it churning out more code or less code? Is it to have less bugs in production or shipping code more often? Is it doing a lot of things or just one thing? Let’s think about this for a moment. I believe developer productivity is about getting more things […]


Improving the usability of Aftonbladet Video-clip pages

We have recently started the process of improving the usability of video-clip pages. In order to get an idea of where Aftonbladet stands compared to other world-class online video/news providers, we conducted an online test answered by 110 visitors of Aftonbladet TV. In this test we compared their perception of an Aftonbladet TV video-clip page […]


Schibsted’s 1st iOS Deployment Meet-up

Schibsted’s 1st iOS Deployment Meet-up Thursday, 28th of April 2016: getting to know each other, guests arrive Friday, 29th of April 2016: the meet-up date We here at Aftonbladet had been planning on having a meet-up with iOS developers across various Schibsted companies for many months. We had a range of topics in mind for […]


Hackday: The Future of Storytelling is social, engaging and rewarding

We gathered students, journalists, developers and designers to get together and conceptualize something new for the news industry. This was our first organized hack event – The Future of Storytelling Hack. The hack was a team-based, news-media-focused prototyping and experimentation event within storytelling over two days at Kungsbrohuset, Schibsted and Aftonbladets headquarter in Stockholm. A good story used to […]