Reactive Programming is a relatively new and interesting programming paradigm that has picked up quite a bit of popularity lately. Out of curiosity, I did a bit of research over the weekend. In this blog post I will summarize what I learned and try to explain what RP to any novice out there. Also, I show you how to use the Reactive Extensions for Ruby. Let’s dive in!
I rarely have strong opinions, but I really think that to understand anything in life, you need to understand the motivation behind it. In this case, to understand what Reactive Programming is, we need to see what problems it is solving.
All of the programming paradigms that we know of at this point of time are invented more than 20 years ago. Yes, even functional programming. In fact, it was invented like 60 years ago. The problem is, just like with anything that evolves, priorities change.
In our case, the internet happened. Sure, +20 years ago the internet did exist, but it had less users then the count of views that a popular video on YouTube has today. Going forward 15-10 years ago, the internet grew enough, so we felt the need for a ton of data processing and asynchronous behaviour.
Applications needs have changed, from poll-based to full reactive applications, where the data is pushed to us. Each time, we’re adding more complexity, more data, and asynchronous behavior to our applications. So, reactive programming is a way to manage all of that complexity, mindset switch included.
The word invented might hurt someone’s ears. At the low level, the paradigm is
basically a construct of two design patterns that have been around for more then
20 years. Actually, one of the most popular design patterns book, the Gang of
Four book, covers these two design patterns: the Iterable and the
patterns. These two patterns are behavioral design patterns, which characterize
the interaction and responsibility of objects and classes.
Taken from the GoF book:
The key idea in this pattern (the Iterator) is to take the responsibility for access and traversal out of the list object and put it into an iterator object. The Iterator class defines an interface for accessing the list’s elements. An iterator object is responsible for keeping track of the current element; that is, it knows which elements have been traversed already.
Sounds familiar? I am sure it does. Ruby’s
Enumerable module does just that,
it returns an enumerator, which encapsulates the data and the traversal methods.
Okay, let’s keep this short then - an iterator in Ruby is an instance of a class
that includes the
Enumerable module. Which, it’s pretty much any collection.
The observer pattern is a design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. Usually, it’s used to implement distributed event handling systems.
Basically, the subjects are the objects that send the messages to the objects that observe the subjects (damn!). The subjects push the messages to the observers, which is why this is called the Observer Pattern.
Ruby ships with the Observable module in it’s standard library, which provides a simple mechanism for one object (subject) to inform a set of subscribers (observers) of any state change.
Now that we have an understanding of both, the Iterator and the Observer patterns, it’s time for the Reactive Programming paradigm.
According to the Reactive Manifesto, Reactive Systems are: Responsive, Resilient, Elastic and Message Driven. I don’t know about you, but these type of definitions confuse me a lot. In the way that I understand the Reactive Manifesto, Reactive Systems are asynchronous, fault tolerant, scalable and they communicate with non-blocking message-passing.
But, what interests us is the implementation, especially in Ruby. Would you be
surprised if I tell you that on the surface, the reactive programming paradigm
is basically an abstraction on top of the the
Observer pattern in combination
Don’t believe me? Let’s see a few examples.
From the README:
The Reactive Extensions for Ruby (or, RxRuby) is a set of libraries to compose asynchronous and event-based programs using observable collections and Enumerable module style composition in Ruby.
There, told ya?
RxRuby is a library, which does all of the abstractions for us,
so we can easily start with Reactive Programming in Ruby. Neat, eh?
Let’s see how
RxRuby works, in it’s simplest form.
RxRuby::Observable is just a stream. A stream is a subject (or, an object)
that you can subscribe to (or, observe). Now, the
itself doesn’t do anything, unless we invoke a method on it. Let’s carry on
with the example:
What do you think will happen here? Let’s break it down. The object that we
receive is a just the number 42, wrapped as an observable. Since the observable
implements (most of) the
Enumerable methods, we can do anything with it. But,
to avoid any complication in this example, we will just
subscribe to the
observable and pass in a lambda. The lambda will be invoked on everytime the
stream pushes any data (or, in this case, just once).
The output of the example will be:
Observing on an array
Now, since we have a lot of the methods from the
Enumerable mixin available,
let’s do something with an array. There’s two ways of working with arrays in
RxRuby: via ranges and via plain arrays.
This will return:
Let’s break it down. First, we create an observable range, with the numbers from
1 to 10. Then, we invoke
select on the observable, with a lambda as a parameter.
The lambda takes each number of the range as a parameter, and filters all even
numbers from the observable, returning a new observable. Then, we invoke
on it, which sums all of the even numbers.
At the end, we
subscribe on the observable that
sum returns. By subscribing
we basically “watch over” the observable (or, the stream of data) and invoke the
lambda that we pass as an argument to the
subscribe. Any time the observable
pushes any data, it will go through this “funnel” and invoke the last lambda at
the end, which will print out the message. the observables push any data we
Doing this via arrays is very similar:
This snippet will also return the same message at the end. The only difference here is that we create an observable from an array.
The documentation on RxRuby is still scarce, but fortunately for us there are a lot of examples in the Github repo.
As for me - I am looking for anyone that’s proficient with RxRuby, to review my RxRuby Koans, so we can get it moving somewhere.
Some links I used while writing this article, that you might find interesting: