9

I was reading about Reactive programming, and came across this article The introduction to Reactive Programming you've been missing with the quote I put in the question title:

Reactive programming is programming with asynchronous data streams.

but this confuses me a bit. For example, the most common example of Reactive programming that I've heard about is a spreadsheet program that has computed values.

What's asynchronous there or requires streams in that case? I understand that perhaps the computed values could be implemented with a stream, but do they really need to be? Couldn't they also be made with event listeners?

m0meni
  • 773
  • 1
  • 6
  • 12
  • The article is primarily aimed at web sites with a constant flow of data going between the page and one or more servers. "Reactive" in this case is a title rather than an action. – Adam Zuckerman Apr 27 '16 at 23:07
  • @AdamZuckerman And he's a large advocate of RxJS, creator of his own stream library called xstream, and he's the creator of Cycle.js, which relies entirely on streams. I'd just like a more general viewpoint, and definition for reactive programming. He's one of the only people really talking about it on the frontend – m0meni Apr 27 '16 at 23:08

1 Answers1

13

The most common example of Reactive programming that I've heard about is a spreadsheet program that has computed values.

Personally, I would think about a spreadsheet more as a hybrid between functional and dataflow programming, but I can see how you can think about reactively.

What's asynchronous there or requires streams in that case?

There is an asynchronous stream of user actions. The stream(s) are the values the user inputs into the cells. Everytime the user changes a cell value, that's a new value in the stream.

Couldn't they also be made with event listeners?

Yes.

Everything could also be made with event listeners. Reactive Programming is still "only" Turing-complete. Everything you can do with Reactive Programming, can also be done with Event Listeners or Continuations or Callbacks or … Event Listeners and Reactive Programming are two ways of modeling asynchrony. Both can model the same things. Proponents of Reactive Programming do not argue that they can model things that others cannot. They argue that Reactive Programming can model (at least some things) better than other approaches.

Streams are a convenient tool for thinking about Reactive Programming, because of one important reason: familiarity.

In Interactive Programming, the single most important concept is iterating over a collection. It's one of the first things one learns when learning to program. The each method and the Enumerable mixin in Ruby, the foreach statement in C♯ and the IEnumerable/IEnumerator pair of interfaces in .NET, the enhanced for loop and the Iterable/Iterator pair of interfaces in Java, the Traversable trait in Scala, iterators and loops in C++, you name it. Collections and iterating are extremely important, and everybody knows how to do it.

Streams allow you to re-use all that knowledge by framing Reactive Programming in a setting very similar to iterating over a collection, with just two differences: instead of you pulling out an element from the collection when you want, the collection pushes an element at you when it wants. That's it. Everything else stays the same.

In fact, the relationship is much more than just familiarity. There is actually a deep mathematical relationship between the two: Reactive Programming with Streams is the category-theoretical dual of Interactive Programming with Collections. The Subject/Observer Pattern is the category-theoretical dual of the Iterator Pattern.

It was Erik Meijer who discovered this, and he used it to enormous effect in .NET. He mechanically derived the IObservable/IObserver pair of interfaces simply by stupidly dualizing IEnumerable/IEnumerator. The fact that they are duals means that you can literally just swap the parameter types and return types of the methods without even having to think about what you are doing.

And the really cool thing is that duals are still closely related in structure, and a lot of things that work for the original thing also work for the dual. In .NET, for example, IEnumerable/IEnumerator form a monad that can be used with LINQ. And it turns out, IObservable/IObserver also form a monad, and thus also can be used with LINQ in exactly the same way that IEnumerable/IEnumerator can. In other words, by framing the problem of Reactive Programming in terms of Streams, you can use the exact same tools for Reactive Programming that you are already used to from Interactive Programming. You can literally write the same LINQ query regardless of whether you are iterating over an array or subscribing to an event stream.

Mapping, folding, reducing, flatMapping, filtering, transforming, partitioning, merging, splitting, … Streams is exactly the same as mapping, folding, reducing, flatMapping, filtering, transforming, partitioning, merging, splitting, … collections.

That's the power of Streams. They let you at least think like your are iterating over collections, and with some clever libraries, even write code like you would with collections.

Jörg W Mittag
  • 101,921
  • 24
  • 218
  • 318
  • So event listening is separate from reactive programming, and reactive programming is explicitly about streams? Also why is a user action considered async? – m0meni Apr 28 '16 at 00:35
  • Thanks for all the detail! One more thing. How do you differentiate reactive programming and functional reactive programming? I see people use them almost interchangeably. – m0meni Apr 28 '16 at 01:07
  • There are two different definitions of "Reactive Programming". One is simply the opposite (or rather dual) of Interactive Programming: programming where you react to the environment instead of you interacting with the environment. Think about this like the term "Iteration". Functional Reactive Programming, Events, Observers, etc. are just different ways of Reactive Programming, just like for loops, while loops, iterators etc. are different ways of iterating. So, FRP is a specific technique for doing RP. When people like Erik Meijer took ideas from FRP and re-interpreted them in the context of – Jörg W Mittag Apr 28 '16 at 01:12
  • … OO, this was also called RP, because it is kind-of like FRP, but not in a functional setting. FRP - F == RP. So, we now have two different interpretations of the term RP: FRP is a kind of RP (in the broad sense), as well as RP (in the narrow sense) is a kind of RP (in the broad sense). Both FRP and RP (in the narrow sense) are "cousins". – Jörg W Mittag Apr 28 '16 at 01:14
  • How would you implement RP in a OO environment? You mention "Mapping, folding, reducing, flatMapping, filtering, transforming, partitioning, merging, splitting, … Streams is exactly the same as mapping, folding, reducing, flatMapping, filtering, transforming, partitioning, merging, splitting, … collections." That sounds a lot like functional programming. – m0meni Apr 28 '16 at 01:17