Michiel Overeem

Certified Rx Developer

Certified Rx Developer

My current company gives every employee a training budget. This budget can be spend on every training that you like, there is no need to ask permission up front (but how you spend it is part of the evaluation). So when Erik Meijer asked on twitter if people wanted to follow a certified Rx developer training, I had a training to spend my money on.

I had already taken the coursera course Principles of Reactive Programming (which is highly recommended!), but the Rx stuff had not really sunk in yet. That is why I started a new project. But still, the opportunity to learn from Erik, the one that started the whole Rx movement (years ago)? I had to be there :-)

This blog post is a combination of a summary of Rx and my experience following the certified Rx developer training. Let me start with the last, my experience. Erik is a great teacher. Not only is he super smart, he is also funny, entertaining and a nice person to chat with. But more, he is a real hacker, not some scientist that cannot write code. He honestly ended our lunch to start hacking on some idea (with goto’s for crying out loud)!

So, what is Rx anyway? I could point you to this great introduction, or to the code. But it might be fun to see if I can explain some things. I like the path that Erik took, which started not with Rx, but with monads. Those things always sound awful. In the Haskell community, there is a quote saying that they should have called those things warm fuzzy things, because that sounds so much more fun. But monad it is. But before we get to monads, let us first look at exceptions.

Exceptions

When programming C# and JavaScript (my primarly languages), exceptions are used to abort the execution when something happends that you did not expect. Which exceptions a method might throw is not visible from the outside. The method signature does not tell you about those cases (in Java you have checked exceptions, not in C#). So when we have a method like this, the signature is lying to us!

#c#
private int DoSomething(int number)
{
  if(number < 0) {
    throw new Exception("No negative numbers allowed.");
  }

  return number * number;
}

It tells us that this method takes a integer as argument, and returns an integer. There is however, another possible outcome: the exception. So the effect of failing is hidden from us. To make this more explicit, we introduce the Try type. Using this will give us the following method (implementing the Try type is left as an exercise to the reader).

#c#
private Try&lt;int&gt; DoSomething(int number)
{
  if(number < 0) {
    return Try { Failure = new Exception("No negative numbers allowed.") };
  }
 
  return Try { Success = number * number };
}

This signature shows us that the method has two possible outputs: an integer, or an error. We have made the possibility of failure explicit.

The four essential effects in programming

Erik Meijer

The Try type is essential for programming, because we use it for synchronous, single values. If we move from single values to many values we need to use another type, the Iterable type. In C#, this is the Enumerable type. But this type is still synchronous. This means that asking values from an Iterable blocks the execution till all values are given. You are pulling values from the iterable and that blocks the execution. When you want to develop a scalable, responsive system, blocking is not done: asynchronous is the way to go.

If we move from a synchronous single value to an asynchronous single value, we need yet another type, the Future type. This type makes it explicit that we have latency. It might take a while for a value to be available. In C#, this is done using the Task type, which corresponds with Futures. In JavaScript we have the Future/Promise objects.

The last step is from a asynchronous single value to multiple values, asychronously. That is where the Observable type comes into play. And that, that is the heart of Rx. To summarise these four effects:

SingleMany
SynchronousTry<T>Iterable<T>
AsynchronousFuture<T>l;Observable<T>

But what about monads? And why is Rx so special? Untill now I only explained four effects and the corresponding types. Let’s move on to monads now.

Monads

So what is a monad? I do not pretend to understand it better then others, so I will not try to write a formal (or informal for that matter) explanation. Search google if you want the real stuff, or read this one! For now, all you need to grasp is that a monad is a datastructure that comes with a set of functions, of which I will give you three examples in C#:

#c#
public static Something&lt;U&gt; FlatMap(this Something&lt;T&gt; source, Func&lt;T, Something&lt;U&gt;&gt; func)

public static Something&lt;U&gt; Map(this Something&lt;T&gt; source, Func&lt;T, U&gt; func)   

public static Something&lt;U&gt; Filter(this Something&lt;T&gt; source, Func&lt;T, bool&gt; func)   

Now, these types are very general. But you could substitute the generic Something type with a couple of familiar types. For instance with Try. Or with Future, Iterable. You might even substite it with Observable.

A monad is a general data structure that gives you a set of common operations (others are zip and flatten). From them, you can build lots of stuff. You can filter, combine and project your data. And that is the power of monads. They give you a basic set of functions that work on all four effects: synchronous, asynchronous, single or many.

By the way, the names FlatMap, Map and Filter seem new. But just put them next to the LINQ functions SelectMany, Select and Where. They do look familiar now, don’t they?

Rx

Rx thus fills in the last quadrant, the missing piece: many asynchronous values. Now that I write it down, it all seems very simple and nothing new in general. But the Rx library gives you an implementation of the Observable type, with all the monad functions implemented. It allows you to turn any stream of data (from a database, from a webservice, from an input device, from an user) into an Observable that you can then filter, combine and project. And all of this is asynchronous by default. You are forced to think about latency, which is a good thing if you want your app to stay responsive.

In the training, Erik went on the give some example use cases. Projecting earthquakes on a map for instance. Or updating the average earthquake strength per region while earthquake data comes in. The guys at github used Rx to build a reactive UI. Netflix uses Rx. Square (could not find any source but Erik told us) and SoundCloud as well.

One thing you have to keep in mind, is that Rx is not about concurrency, or parallelism. It is about asynchronous computations. However, you could use it for concurrency and parallelism, using the schedulers that they implemented. But that is not the key point.

Take aways

So what are the take aways from this training and Rx in general? Let me offer a small list of things that I can think of: