Closures in Swift: The sequel
Since I started learning Swift closures, I find myself actually seeking them out and trying to inject them into my work more often. It is in this same spirit that I bumped into Functional Programming and inevitably Higher Order Functions. Functional programming has gained it’s place at the table as one of the more superior ways of programming. This is however not about functional programming. This is about my learnings in closures; how they are employed in higher order functions and by extension, what role they have in functional programming. If you have not explored functional programming, I would recommend you do. Put your 🐽 in there, see if you like it. You know what they say, there is no harmful knowledge. This piece will borrow largely from this tutorial by Ray Wanderlich majorly because I found it very well explained and fun to read. Aren’t Ray Wanderlich tutorials just amazing? 🙌
To follow along this piece, you will need an elementary knowledge of closures. Not your cup of tea? Worry not, I wrote up on my learnings when they were also not my cup of tea here.
Before we go into functional programming, let’s slip back into our comfort zone.
Here is something, we have all most probably used. You have a list, you want to loop over it and perform a certain operation. What will you do, summon the
forloop! This is what is referred to as imperative programming. This looks pretty neat, you understand it and it’s easy to write. So why fix what is not broken? Here’s why!
The above example is actually just one line of code, it’s neat and even though might not look like it now, it is much easier to write. These are just a few advantages we see, we will look at other more massive benefits as we proceed.
Do I have your interest? Now we can attempt to define what functional programming is.
Functional Programming who are you?
Functional programming is paradigm that focuses on mathematical computations and avoids state and mutable data.
Once we avoid state and mutable data, we fill the void by turning to higher order functions. This seems a good time as any to define higher order functions.
Higher Order Functions
Higher order functions are functions that accept other functions as an argument, can return a function or both. When we were exploring closures here, we mentioned that closures are referred to as higher order functions 😃.
Above we have a little problem that we will use to look at a couple of higher order functions. This is a book store model. There are books with all kinds of components and a list of books.
This is a closure that accepts a function as it’s parameter and returns an array of the same length after the function has been applied to every element in the array.
We want to get a list of all the names of the books in our little book store. How do we do it?
Here we will implement
map . Wait a minute, didn’t we say that map accepts a function? I do not see it accepting any function. What sorcery is this 😟? Well, let’s look at how we got here.
Do you remember
$0? When we were learning closures, we discovered it is a shorthand way of referring to parameters of a function. In this case, we refer to the very first and in our case the only parameter of the function. Does the above line of code look oddly familiar? This is because when we were learning closures we looked at a certain flavor of closures known as trailing closures. This is a trailing closure.
Filter accepts another function as a parameter and this other function accepts a single value from the array. It then applies the input function to each element of the calling array and returns another array that has only elements for which the parameter function returns true.
I know, that sounds like quite a mouthful to say.
What if we wanted to find all the kid-friendly books?
Let’s get down and dirty 😺
How we do it?
- Create a list that will take in the new list of kid-friendly books
- Loop through the books and set a condition that the book has to be of category .
- Return the filtered list
This works, however it is clearly the imperative way. We tell the compiler what we want and how we want, how about we go in and do it declaratively
This is one way of doing it.
- Define the function you want filter to apply to every element. The function should return a
- Use the function as a parameter for the filter function
The function then returns a new array only with the elements that satisfied the condition it applied.
You remember trailing closures. Well, we could summon one here and just inject it into the closure.
It takes two parameters; a starting value and the second is a function that combines a value with elements in the collection to produce another value.
Note: The value to be added to the elements of the array should be of the same type or you will get an error.
Someone wants to buy all the books in our bookshop, we need to get the cost of everything in it. How do we do it?
That get’s the job done right?
Both closures give you the same responses only that one is neater. 😃
This takes in two collection types and combines them into a single one.
Say we have another floor in this bookshop that has different books and we store them in a different array.
If we wanted to find all the books in our bookshop, we would need to flatten out the two arrays into one.
see, simple and fast!
What if we could combine everything we have learnt into one giant super Higher Order Function?
What if we could solve Problem1, Problem2, problem3 and Problem4 all at a go? 💡
We want to get the cost of all the kid friendly books that are in both lists.
We need to;
- Flat map the two lists into one list
- filter for the category of books we want to get
- use map to extract for the cost of the books
- reduce to get the total cost of the books
Using chaining we get one magical mega all powerful Higher Order Function or should I say Highest order function 😃.
Why Functional Programming
I promised to tell you the advantages of going functional. Before you accuse me of click baiting you, though not much of a click bait really😆, let’s look at those.
- As you may have observed, we have definitely come up with cleaner code
- The ability to separate your code without state ensures you will not have concurrency problems during multithreading and that kind of thing.
- As you may have observed, with functional programming code is very modular. This will come in handy when testing as it is easy to write a test for a function that is standalone and does not modify anything outside of itself.
- lastly, don’t you hate it when a variable has changed and you can’t for the life of you figure out why that happened? Well, with Functional programming that is a thing of the past
Opportunity for growth
If you look at the Highest Order Function (that’s right, it’s now a thing), you will observe the order in which I have arranged the functions. It is important to be cognizant of this so that you come up with optimized functions.