Be gentle with pushing functional patterns into iOS

One thing about trends is that we try really hard to follow them no matter what it takes. Sometimes they don’t bring that much value (or even worse), but it doesn’t matter… We’ve already hopped on the trend-train!🚂

I see a lot of messing around Swift being considered as a multiparadigm language, or even functional language (not pure, but still). There are good resources proving it’s possible. Of course there are people on the other side, proving that Swift isn’t functional. I won’t waste your time on this debate. I’d rather show you how you can become a conscious Swift programmer, and not a puppet, blindly following trends.

From time to time you can see developers going too deep into functional approaches in iOS. Thankfully they share this with all of us, so we can be aware:

It’s really good that we’re trying to be on time with new trends, new frameworks and everything, but no matter what we’ll do we’ll hit at some point UIKit, and it’s like smelling salts for iOS developers.

That’s why I’ve learned that every fully functional library on iOS is just a fairy tale. It’s not possible to completely apply it to the application which relies on UIKit. It doesn’t mean that we should forget about functional programming, instead should become more generic about it, and not rely on solutions form other technologies (just like we don’t write Objective-C in Swift anymore). What I mean by this is that we should start applying small functional patterns instead of whole frameworks. We should improve our codebases chunk by chunk. We should start noticing the possibilities for functional patterns in it. Trust me, it can be a win-win situation — you’re following trends, improving your codebase, but also still feeling like home in it.

I’ll show you a couple of well know functional patterns which can address following problems:

  • Testing
  • Modularity
  • Extendability
  • Code safety
  • Better UX

No further ado, let’s jump into some coding and some usecases 😉


First thing I’d like to address are Side Effects. It’s a well know thing for all functional programmers, but I bet majority of OO programmers doesn’t know about them at all, simply because they don’t have to…

A function or expression is said to have a side effect if it modifies some state outside its scope or has an observable interaction with its calling functions or the outside world.

Let’s translate this to iOS world. Basic component of our apps is really a stateful thing and its name is UIViewController. Just think about it. We have a lot of properties driven by a lot of method which return Void. Take a look at this viewDidLoad implementation:

func viewDidLoad() {
super.viewDidLoad()
    configureLabel()
    if production {
configureProductionEnv()
} else {
showExtendedLogs()
}
}

It’s really a common thing to configure stuff in viewDidLoad(especially when working with Storyboards). It’s not obvious to spot side effects just by looking at this code, so let’s take a glimpse atconfigureLabel:

func configureLabel() {
let labelConstraints = generateLabelConstraints()
    for constraint in labelConstraints {
constraints.append(LayoutConstraint(constraint))
}
    label.text = “This is wrong!”.uppercaseString
label.font = UIFont(name: “CirceBold”, size: 11)
label.textColor = UIColor.blueColor()
label.textAlignment = .Center
label.numberOfLines = 1
label.constraints = constraints
}

Now it should be clear…
We’re setting constraintsand label properties in this method and hiding this in a method which returns Void. Again, I’d say it’s a common scenario in iOS, since we see this pattern everywhere. You may wonder, what type of hardness does this code introduce?

I don’t write tests, because I don’t know where to start. Everything is hidden from me, and I’d have to mock whole UIViewControllers just to write some dumb unit tests…

Maybe you’re the guy from this description, if not (I hope so), you’ve probably seen a couple of your friends saying this kind of things. Now imagine this method actually returning something meaningful, like configured instance of UIButton. That would actually make this method easy for testing, right? You simply assign the result of this method to property. I’ll leave implementation details to you 💪

Being aware of just one thing can really improve testability of your code, so let’s follow this path and introduce next concept which gives us even more power while writing our tests. Functional programmers call them Pure Functions, and while this name is super fancy, the underlying concepts is really simple:

  • Pure functions can be named as predictable functions. We can be sure that we’ll have the same result every time we pass the same set of input arguments.
  • Pure functions have no hidden dependencies and they don’t produce side effects.

Many iOS developers may connect pure functions with Dependency Injection, but on functions level. In my opinion, it’s a good if you consider it this way. We simply pass something to the method instead of reaching for some dependencies inside its body.
Imagine configureLabel, to have header like this:

func configureLabel(constraints: [LayoutConstraint]) -> UILabel {
// Implementation here
}

Now you can pass some fake LayoutConstraints and manipulate results in your test cases. Super simple and super effective! 🙌


I may have gotten a little bit too excited about the simplicity and benefit of the previous two functional patterns. We’re still in UIKit, so we’re trapped in UIViewControllers and if we don’t want to mock them, we have to do something about it. Of course, there’s nothing wrong with mocking whole UIViewControllers, but why testing something which has been alrady heavily tested by Apple? :trollface:
Joking aside, let’s move on to real stuff. In Haskell (Yup, I had to boast about it 🤷‍♂️) there’s a thing called Typeclasses, and I bet the code sample below will be enough for you to guess what’s its younger and less functional brother in Swift:

class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)

Just to help you out a bit, here’s the same thing taken directly from Swift’s repository:

public protocol Equatable { 
static func == (lhs: Self, rhs: Self) -> Bool
}

Exactly! What I’d like to point to you is Protocol Oriented Programming introduced by Apple in 2015, but known by others for much longer… 😜 
With POP you can easily model behaviors, compose them and and apply to other classes — especially to mentioned earlier UIViewController! We can extracts our code a little bit from UIKit, so… NO MORE MOCKING OF BIG CLASSES! You can create mocks just for your protocols and test them in isolation 👍
It may seem like I’m just talking the talk here, but believe me, I’m not the one to discover this capabilities of protocols. I won’t write some samples, as this is a topic for a whole new article, but there are some useful resources out in the wild covering this topic.


I realize that all of the mentioned things may be well-known to you, but from my experience — we tend to forget about them, since many times they don’t have proper names in Swift. Same thing is with the last pattern I’d like to share with you in this article.
We’ll take a really quick look at Algebraic Data Types (this is a cool name, huh? 😎). Following the previous pattern, here’s your Haskell snippet:

data BinaryTree a = Empty | Node (BinaryTree a) a (BinaryTree a)

Are you home already? If not, here’s a Swift version:

enum BinaryTree<T> {
case empty
indirect case node(BinaryTree, T, BinaryTree)
}

Maybe I did suprise you by telling you thatenums are actually a thing from functional world. You probably used them, but maybe you’re not sure why… I won’t try convince you, I’ll just redirect you to a really good article written by Soroush explaining why you shouldn’t have optional properties in your UIViewControllers — yes, it’s about enums 😜


This article was already a long one, and it’s just a peak of the mountain… I hope I woke up a ƛ functional programmer ƛ in you who now will seek for more (higher order functions, monoids, functors, applicatives, monads, immutability)!

Be sure to apply simple concepts and benefit from them. Don’t reach for whole approaches driven by frameworks, cause Swift on iOS isn’t functional, and never will be! 
Even if some brave soul will take plain Swift and implement functional web framework in it. Well, it still won’t be a pure functional thing, so why not take the best of what we have right now and focus on it? Just don’t try to write Haskell in Swift’s syntax, ok? We know it’s not good from the past when we used to write Objecive-C in Swift’s syntax…


This article was driven by the talk I gave at CocoaHeads Kraków. You can find slides at Speaker Deck.

I hope you liked it! ❤️