How is reactive programming different than event-driven programming?
Asked Answered
E

5

73

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.

Exogenous answered 28/12, 2015 at 14:11 Comment(3)
related: Advantage of Functional Reactive Programming over event-listenersNanon
Check out: oreilly.com/ideas/reactive-programming-vs-reactive-systemsLegit
EDA = reactive programming + DDDFatidic
A
33

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.

Aideaidedecamp answered 29/12, 2015 at 10:38 Comment(0)
T
128

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.

  • Imperative programming: focuses on how 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.

Thoer answered 28/12, 2015 at 15:55 Comment(6)
Promises, critically, are more than just a flow of execution: they're a persistence model, representing the state of that execution, and its final output. Because they're persistent, they can be stored, shared, referenced, passed. Whereas, in a purely event-driven system, you're lacking the history if you begin listening after-the-fact, and you (generally) have to listen for all events, to hear any events. A promise gives you the ability to encapsulate and subscribe to a limited, single-purpose event stream, and also to check the state of that event-stream at any time in the future.Legit
Overall, this post is a great read on principles. For more, see: oreilly.com/ideas/reactive-programming-vs-reactive-systemsLegit
I like your answer is better than the accepted, but all of this seems to boil down to our industry's seemingly-ever-present need to generate new buzzwords. Your statement about differentiating between event-driven programming and so-called "reactive programming" is a stretch, to me. "Reactive programming deals with data. Ultimately this is a special case of event-driven programming." Only a special case for those with a limited view of what an event is, I suppose. Either way, death to anemic buzzwords!!!Saiff
@JasonBunting Sure, buzzwords aren't useful in and of themselves, but distinguishing between more general and specific versions of a concept is relatively normal. We say "object", "machine", "automobile", "car", "sedan", and "Honda Civic" all of which are special cases of the former. When someone says "event driving programming" this should conjure up different conceptual images in your head than "reactive programming" if you are familiar with both terms.Thoer
@FrankBryce - I concede the point, I am just bitching about the propensity for new buzzwords. While a "Honda Civic" might have features unique to it that other instances of "sedans" might not have, "reactive programming" seems to have no features unique to it when compared to "event driven programming," other than a neat new buzzword; hardly a nice feature to have, if you ask me. Such buzzwords merely cramp conversation that might otherwise have clarity. I suppose that's to be expected when talking with those ignorant to established vernacular.Saiff
Nice answer, but I would (according to you description) argue that event-programming is the special case of reactive programming. Because in reactive we say: "data have changed" regardless of the change and regardless of what part of data has changed, on the other hand in event-programming in event-programming we are more interested in the details for example "Name has changed" and "Address has changed" are two different things. Also I would argue that event are special type of data.Tullius
A
33

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.

Aideaidedecamp answered 29/12, 2015 at 10:38 Comment(0)
O
7

The difference is mostly related to how you "configure" (or declare) things convention: what happens to something when something other happens.

In reactive programming, you declare a reaction to a change. You don't have to forsee this reaction needed to that change upfront, you may add - declare - this reaction anytime later. Therefore, it might be considered a "pull" or "watch" strategy.

Therefore, in reactive programming, you hook up to / watch data which you know that exist. Data is crucial here.

Example: a user clicked an item on the page -> update the counter how many clicks user made.

Example Calculator App: the calculator display is bound to all buttons, and reacts with any change (clicks on the buttons) with its own change on the display. Buttons don't have awareness that their clicks can be utilized by any other parts.

In event-driven programming, you trigger an event in a certain situation in the imperative-written code. You need to be explicit upfront here, because the event needs to be triggered first in order to be received later - because basically you push the event in the "change happening" part of code. So it is a "push" strategy.

Therefore, in event-driven programming, you push an event in a certain situation that maybe would be received by some other parts of code. Situation is important here, data does not matter.

Example: someone has visited the contact page -> trigger an event (which might not be received at all in the end by any listener, which is typical case for many modules and libraries).

Example Calculator App: the calculator display is just a listener, and the buttons trigger events. Buttons need to know that they exist in a certain context (but - thanks to the event-listener pattern - don't have to know what exactly is that context), and therefore they are required to trigger an event.

So in most, they are just different conventions. Look at this simple example. The imperative approach example:

event: perform some operation on a, e.g. a += value, and trigger the event
listener: counter++

And the reactive declarative approach example:

counter: whenever an operation on a occurs, react with this: counter++

No need in the last example to trigger anything - you just "hook up" with a reaction to anything that may happen.

You may say, then, that reaction is bound to a in reactive approach, while in imperative event-driven approach you push an event that can be later received by a listener - and since this type of approach is not related by any means to data, you may change this: a += value to anything else later, even removing a completely.

Event driven approach has nothing to do with data essentially. Reactive programmin is basically about data.

So as you see, reactive programming is data-oriented (change in data reacts with triggering other code), while event-driven programming is process-oriented (it doesn't matter if and what data change, if any - you just trigger an event that would be received by some other parts of code). In the latter case, you need to know that this "informing" the other parts of code is required, and you have to then foresee that the event should be triggered. In the former case, you don't have to do that, you can do it any time, or not at all - no triggering events required - but the trick here is that there must be "something" that you can hook up to with your reaction declaration, kind of watchers which allow you to react to the watched changes.

Offing answered 21/5, 2020 at 17:32 Comment(2)
Great answer. By the way, I wonder which type you personally more prefer, reactive-driven or event-driven. In web ecosystems, React Hook prevails in recent years; while in traditional desktop UI writing, event-driven style seems still to be a mainstream, and QT's signal/slots mechanism are highly praised for it's mature design and convenience. I wonder why web service don't choose to use event-driven, and vice versa - why data-driven programming don't affect the desktop programming world. Might it be the case that web developers also wish event-driven style, however this is hard on browser?Negress
It depends on the project. However, reactive approach is specific and best suited for UI. So as a general rule I prefer traditional approach, as I mainly program the backend.Offing
W
1

Reactive programming is all about streams, it could be streams of events, or anything else. It is on emitting/announcing these streams or subscribing/watching these streams or stream transformations that lead to some events. So both programming paradigms are related.

Wylie answered 8/12, 2017 at 19:5 Comment(0)
G
0

To me it's like comparing oranges to apples. Let's try to define in a simple way what is what and so distinguish the things:

Reactive programming is a programming paradigm that is applied when one wants to achieve a functionality akin to data binding in libraries like KnockoutJS. Also an example would be Excel formulas: all cells are like variables in memory. There are those that simply hold some data and those which are computed from that data. If the former changes, so does the latter. Pay attention that the paradigm is about lower-level implementation; when someone is talking about reactive programming they are referring to data, its changes and what happens when it mutates.

On the other hand, event-driven programming is about system architecture. According to that paradigm events and event handlers are the basis of a system and everything is built upon and around them. Common examples would be UI and web server multiplexing. Do you feel how all this is different? The paradigm is applied on the level of a whole system or a subsystem.

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

Promise is a tool to achieve concurrency and specific order of execution. It can be used in any paradigm.

In practice the paradigms serve different purposes and at different levels. You can have event-driven design with some bits of reactive code. You can have distributed system that uses reactive design patterns. However, events are ultimately higher-level concept. Reactive is about data and its re-evaluation, an approach for implementation or its detail, and events are something that naturally come up from a case and drive your design.

Garrison answered 28/12, 2015 at 16:22 Comment(1)
"event-driven programming is about system architecture" - says who? You are trying to make an apple an orange. EVERY change can be considered an event. UI changes are still data changes. "Web server multiplexing" (whatever the hell that is), still consists of data changes. Every event in this world is a data change, and vice versa, if you choose to look at it that way. And that is the crux of being a developer: your hopefully-high-fidelity perspective of the problem domain largely decides what approach makes most sense.Saiff

© 2022 - 2024 — McMap. All rights reserved.