Featured Articles
Article in iOS App Development category.
Conquering ReactiveSwift: Introducing Reactive Programming
At its most basic, reactive programming allows you to model time. Learn how to do it with this simple, step-by-step introduction to ReactiveSwift.
“Reactive programming has a steep learning curve.”
I kept hearing this while I was learning functional reactive programming (FRP). Does it ever! Coming to FRP's asynchronous programming from a background of imperative programming, I struggled to grasp various concepts. At its most basic, the benefit of FRP is that it allows you to model time. But this can be hard to get your head around. To help you get over the learning hump, I’m sharing my learning experiences in this “Conquering ReactiveSwift” series. My aim is to provide a step-by-step guide for beginners to learn ReactiveSwift.
This is the first article in the series. It gives an introduction to FRP and explains how it is different from imperative programming.
Imperative vs Functional Reactive
To understand the difference between these programming paradigms, let us invent a project. Suppose we want to implement a user interface having one UILabel (let’s call it label) and one UItextView (let’s call it textView), where the UILabel reflects the text entered in the UITextView. To achieve this behavior, we write this:
func textViewDidChange(_ textView: UITextView) {
label.text = textView.text
}
The above code works just fine. We have been doing this forever. So what is the problem? Let's investigate. Consider the statement, designed to update the text of label:
label.text = textView.text
It is an assignment statement.
What does this mean? This means the text of label becomes equal to the text of textView at the moment of the assignment. This statement does not encapsulate any information about the state of label text before or after the point of the assignment. In other words, the “label.text is equal to textView.text” statement doesn’t necessarily hold true once you add time into the model.
Therefore, we need to encapsulate this statement inside the delegate method—
'textViewDidChange’
— so that the state of the label is consistent. In an imperative way, it is very difficult to represent such a relationship elegantly.
Welcome to Reactive Binding
In reactive programming (in ReactiveSwift specifically), the same problem can be solved through binding.
label.reactive.text <~ textView.reactive.continuousTextValues
This statement implies that the text of label is equal to the text of textView throughout the lifetime of the label.
Did you notice something new? <~ is called the binding operator. The left-hand side of the operator is called the binding target and the right hand side is called binding source. We will explore this later in the Conquering ReactiveSwift series.
In order to visualize the difference in how imperative and reactive programming works, let’s consider typing out the word “hello.”
In an imperative approach, we model our systems in terms of the mutable state. For example, in the above diagram, we are concerned about maintaining the state of the label with each additional piece of text entered.
In FRP, we model the behavior of a system in response to a stream of events. In the above example, we are defining the behavior of the label in response to the stream of text. We are not concerned about maintaining a state in response to an isolated event (i.e., each individual keystroke).
There is another benefit to a reactive approach. With reactive code, the behavior of the label is explicit at the point of declaration. Whereas in an imperative approach, the logic is scattered across various delegate methods. In a long run, it becomes difficult to understand the behavior of an element, increasing the chance of bugs being introduced.
Reactive programming decreases the likelihood of bugs.
Some Useful Definitions
Heinrich Apfelmus (a Haskell functional programmer), boils down the concepts discussed above, in two statements.
From [a] semantic viewpoint, FRP is all about describing a system in terms of time-varying functions instead of mutable state.
By syntactic criterion, FRP is about specifying the dynamic behaviour of a value completely at the time of declaration.
Next in Functional Programming...
Hopefully, this article gives you the motivation to get started with FRP. You can find the sample code here. In the next article, we will discuss the different components of ReactiveSwift.