How is reactive programming different than event-driven programming?

I am learning reactive programming and functional reactive programming in JavaScript. I am very confused.

Wikipedia says that there are various ways to write reactive code such as imperative, OORP and functional. I want to know if event-driven is just an another way to write reactive code?

How is reactive programming related to Promises? I think promises is an alternative to event-driven and callback hell.


How is reactive programming different than event-driven programming?

Event driven programming revolves around so-called events, which are abstract things that programs "fire" when something happens. Other places in your code "listen" for the events and respond with what they need to do when that event happens. For instance, an event could be "user pressed this button" or "the printer is done printing your document".

Reactive programming deals with data. Ultimately this is a special case of event-driven programming. The event: data changed. The event handler: change some more data (if applicable). This concept is usually cleared up when you think of a spreadsheet. If you set cell1 = cell2 + cell3 this implicitly sets two event handlers on the data changed events of cell2 and cell3 to update cell1's data. cell1's data has no such event handler, because no cells depend on it's value.


TL;DR;

Wikipedia says that there are various ways to write reactive code such as imperative, OORP and functional. I want to know if event-driven is just an another way to write reactive code?

The idea of event-driven programming is orthogonal to the idea of imperative vs. OO vs. functional.

  • Imperitive programming: focuses on changing the state of your program will achieve what you want. Most computers are imperative (as opposed to declarative programming), whereas higher level languages are sometimes declarative. Declarative programming, in contrast, deals with writing code that specifies WHAT you want it to do rather than HOW you want the code to do it.
  • Object Oriented programming: deals with so-called objects, or bags of data with associated methods. Differs from functional programming because the methods are able to access the data associated with the objects.
  • Functional programming: deals with re-usable functions, or procedures which take inputs and outputs. This differs from OO programming because functions traditionally do not have the ability to associate data with a function other than the inputs and outputs.

Event driven programming: structures your program in order to deal with ("handle") something else that happens in your program (an "event"). In other words, it structures your code logically like this

When Event1 happens
    do A and B

When Event2 happens
    do B and C

But there are many ways to write this code, and in fact many ways to write the code imperatively, many ways to write it functionally, etc. Here are some examples, though.

Imperatively (with an event loop):

while(true)
    // some other code that you need to do...

    if Event1 then
        do A
        do B
    if Event2 then
        do B
        do C

Object Oriented (with background thread):

// event queue
events = new EventQueue()

handler = new EventHandler()
// creates background thread
Thread.DoInBackground(handler.listenForEvents(events))

// ... other code ...

// fire an event!
events.enqueue(new Event1())

// other file
class EventHandler
    Func listenForEvents(events)
        while(true)
            while events.count > 0
                newEvent = event.dequeue()
                this.handleEvent(newEvent)
            Thread.Sleep(Time.Seconds(1))

    Func handleEvent(event)
        if event is Event1
            this.A()
            this.B()
        if event is Event2
            this.B()
            this.C()

    Func A()
        // do stuff
        return

    Func B()
        // do stuff
        return

    Func C()
        // do stuff
        return

Functional (With language support for events)

on Event(1) do Event1Handler()
on Event(2) do Event2Handler()

Func Event1Handler()
    do A()
    do B()

Func Event2Handler()
    do B()
    do C()

Func A()
    // do stuff
    return

Func B()
    // do stuff
    return

Func C()
    // do stuff
    return

// ... some other code ...

// fire! ... some languages support features like this, and others have
// libraries with APIs that look a lot like this.
fire Event(1)

How is reactive programming related to Promises?

Promises are an abstraction of the flow of program execution which can be summed up as follows:

  • Asker: Whenever you're done doing what you're doing, would you call me back?
  • Answerer: Sure thing, I promise

Nothing really special here, except it's another way to think of the order in which your code is executed. For instance, promises are useful when you make a call to a remote machine. With promises, you can say "call me back when you return from this remote call!". Whichever library you use then promises to call you back when it gets something back from the remote machine. Often, this is useful because it lets you do something else in the meantime without waiting for the call to return.

Punch line: there are a lot of different styles of code, but they don't play too big a role in the pattern of event driven and reactive programming. To my knowledge, you can do event driven and/or reactive programming in most languages.


How is reactive programming related to Promises? I think the promise is an alternative to event-driven and callback hell.

In practice the two are related, I like to call Promises a gateway drug to functional reactive programming.

+----------------------+--------+-------------+
|                      |  Sync  |    Async    |
+----------------------+--------+-------------+
| Single value or null | Option | Promise     |
| Multiple values      | List   | EventStream |
+----------------------+--------+-------------+

Promises can be thought of as EventStreams with one item, or you can think of EventStreams as multiple Promises over time.

Promises can be chained, which is getting close to reactive programming:

getUser() // return promise
   .then((userId) => {
       return fetch("/users/"+userId)
   })
   .then((user) => {
       alert("Fetched user: " + user.name)
   })

The same with bacon.js:

const userStream = userIdStream // EventStream of userIds
   .flatMapLatest((userId) => {
       return Bacon.fromPromise(fetch("/users/"+userId))
   })
const userNameStream = userStream.map((user) => user.name)
userNameStream.onValue((user) => {
   alert("Fetched user: " + user.name)
})

Both code snippets do the same thing, but there is a big difference in thinking: with promises you are thinking about handling a single action with async steps in a clear way - the thinking is imperative, you are doing things step by step. With FRP, you a saying "a stream of usernames is created from the stream of userIds by applying these two transformation steps". When you have a stream of usernames, without caring where they came from, and say "whenever there is a new username, display it to the user".

The FRP coding style will guide you to model your problem as a stream of values (i.e. values that change over time) and the relationships between these values. If you already know Promises, the initial learning curve will be a bit easier, but the main benefit is gained only when you start thinking and modeling the problem differently - it is possible (if not very useful) to do imperative programming with FRP libraries.