
An introduction to reactive programming - nicholasjbs
https://codewords.recurse.com/issues/two/an-introduction-to-reactive-programming
======
MCRed
Nothing against react or reactive, but it's yet another reaction to going down
the wrong path originally -- it seems.

I really don't understand why so many people jump to event driven systems when
genuinely parallel computing is so easy. Specifically Erlang/elixir make it
easy. EASY I tell you!

Yeah, yeah, Erlang has a weird syntax. Ok, so lose two weeks learning it. But
you don't even need to do that-- just learn Elixir which is pretty
comprehensible right off the bat.

Where's the downside? There isn't one. Yet people are going out of their way,
doing all these different projects and attempts whose sole purpose is to try
and fake your way around a problem that was genuinely solved 20 years ago!

To be honest- and maybe I'm wrong and missing something here-- it seems like
so many programmers are following what's hip and popular. V8 was a neat
javascript engine, and then node cam along, so lets jump into callback hell!
Why put up with that when erlang was around and well known?

It's like people choose technologies based on fashion. But that seems too...
pessimistic so I don't want to believe that.

~~~
jamii
I spent a total of 11 months consulting with a company that built a large
(50kloc) financial system in erlang. They had terrible performance problems
that were caused entirely by erlang.

Imagine you have a large amount of data (order books, accounts, etc). You
could put it all in on erlang process, but the gc does not cope well with
large heaps (multi-second pauses). You could store the data outside the heap
(eg ets) but then you pay the cost of copying on every access and have to
tradeoff ease of use (more data per key) vs performance (less data per key).
You could split the data up into many processes and then all your simple
calculations become asynchronous protocols. Have fun debugging the math or
rolling back changes on errors.

I went into that contract with a fondness for erlang. Now I wouldn't touch it
ever again. A naive single-threaded blocking server achieved 10x less code,
40x better throughput and 100x better latency. I used clojure, but any sane
platform would have worked just as well with that design.

~~~
polskibus
I'm curious whether you brought this problem up to the attention of erlang
maintainers, what where their reactions and whether it will be addressed in
the future. GCing large objects on the heap was (perhaps still is despite
improvements) a significant problem also on .NET platform. Not sure whether
this is the case, but have you considered patching the GC yourself or perhaps
moving the problem to BIFs and managing that memory manually (without copying
to ETS) ?

~~~
jamii
The problem was not a few large objects, but large numbers of small objects eg
thousands of orders per market. I considered using manual memory management
but it would have required rewriting most of the code (it was almost all
business logic). I sketched out a prototype in clojure to see whether a better
GC would help and found that even with hastily written code and much abuse of
persistent data structures, the G1 collector could keep the pauses under
100ms. I expect that carefully tuned code would reduce those much further.

------
spectrum1234
I don't understand the hate for such methodologies (in the comments here) that
seem to go down the wrong path. And this is coming from someone who is a
strong proponent of functional programming.

The problem as I see it is pure functional programmers scoff at object
oriented design being so prevalent while object oriented programmers seem so
biased and giddy towards OOP when they haven't even seen the light yet. How
come more people don't see that both are correct?

Both are the result of the market and people reacting (heh) to the market.
This by definition means that both are correct but serve different purposes.
What is fascinating to me is that the web has evolved enough to where user are
expecting results immediately for their actions. This is an amazing time to
live in. Why? Because this means the market is finally very invested in
providing a fluid functional experience for the user. Since the front end is
functional and the backend is OO, its very exciting times as we are the midst
of real time innovation. React is just a tool to help connect these two very
different pieces.

Functional programmers need to get off their high horse and ask themselves why
frameworks are almost entirely object oriented. Object oriented programmers
need to ask themselves why they didn't think of a reactive view sooner. Both
are not 100% right but functional programmers come off as d*cks when they fail
to see there is no continuum of FP principles and that in the real world OOP
makes sense (say to connect the pieces between say a Scala backend and React
front end). You'd think they would realized this sooner though when noting,
for example, that "call by name" usually is more efficient than "call by
value".

~~~
vezzy-fnord
I don't follow how "the market" validates technical paradigms as correct in
any way you describe. Even assuming efficient rational actors, it has always
seemed like the industry adjusts to what has low conceptual overhead and high
familiarity, good advertising and at least reasonable utility.

Nor do I understand how the real-time web indicates we're in an innovative age
just because functional techniques are currently gaining popularity.

For what it's worth, I've never been hostile to OO. I enjoy Smalltalk, I like
Erlang most out of the so-called functional languages, and I've had interest
in the concatenative, logic and array programming paradigms as well, where it
seems most academics and HN users are ruthlessly committed to FP that they
sometimes fail to recognize there's other paradigms as well.

~~~
spectrum1234
1 - yes my definition of the market is actually as simple as part of your
reasoning -> "it has always seemed like the industry adjusts to what has low
conceptual overhead and high familiarity, good advertising and at least
reasonable utility." I'm not sure if you meant it or not but that the perfect
definition of a market and I mean it in that sense. As I've learned from
pursuing my own startups...the market is not rational in any other sense.
Ever.

2 = Because programming has always (in the mainstream sense) been FP platform
+ OOP middleware /frameworks + FP high level layer. Now, looking back, in most
disciplines only 1 or 2 of these are used, but that just means in those
situations the other layers are factored out. In enterprise AND startup
development THIS is the formula that is ever present nowadays.

3- I've heard very good things about Erlang. I agree there are more paradigms.
That is just a continuation of my first point interestingly enough.

I'm pretty new to programming but the benefit of being an unbiased observer is
being able to pick up on all these things. Thank you for the response.

------
woah
So many comments here critical of nonblocking code. What, exactly, is the
downside? Seems to me that any downside is purely syntactical (callback hell
etc. or whatever people like to say when they can't write good nonblocking
code).

So with nonblocking code you have the challenge of a syntax that may be
difficult for some. With any variant of threading, you have the actual real
programming challenge of dealing with state, locking etc. I would much rather
have syntax issues than state issues.

Also the only people who complain about nonblocking code are those who have
been writing threads for 15 years. Why is it that something that is supposedly
so bad and confusing is actually so easy for new programmers to pick up?

~~~
acjohnson55
I find myself wondering the same thing. async-await syntaxes make asynchronous
functions work pretty much the same as synchronous ones syntactically. The
only drawback I can really think of is that you end up Futures going up the
call stack. But this, again, seems to me to just be a detail.

On the other hand, the benefits are really obvious control flow with implicit
synchronization. Scala has shown that it's pretty easy to integrate
asynchronous workflows with actors.

------
pron
Can we please stop using the term reactive programming wrong? Reactive
programming[1], aka dataflow programming, is writing programs that work like a
spreadsheet. Microsoft Excel is a great example of an environment for reactive
programming. _Functional_ reactive programming, or FRP, is simply reactive
programing in a functional style.

What we have here isn't reactive programming at all, but a few patterns (or,
rather, anti-patterns) devised to avoid blocking kernel threads (only some of
them are related to reactive programming). They manage to avoid blocking but
at great cost. If the overhead caused by blocking bothers you, you need to
understand why and realize there are far better ways of avoiding it than these
anti-patterns.

[1]:
[http://en.wikipedia.org/wiki/Reactive_programming](http://en.wikipedia.org/wiki/Reactive_programming)

~~~
mstromb
> there are far better ways of avoiding it than these anti-patterns.

Could you describe or at least point to some of them?

~~~
pron
Lightweight threads. They make blocking free, and allow using constructs far
more suitable for imperative languages. They don't destroy your stack traces,
and don't require you to re-invent exception handling and control flow.
Instead of promises -- simple blocking calls (or blocking futures in some
cases); instead of observables -- blocking queues (aka channels).

Instead of reaching out for ways to avoid blocking, we just make blocking
free.

~~~
eranation
Do you mean co-routines / user threads / green threads? I tend to agree it can
have a serious performance boost in some cases. Not sure why you were down
voted.

There is actually a library for java that adds it via byte code
instrumentation (quasar or something) although not sure it will work for
scala.

But saying that actor model is bad practice, I'm not sure that I accept it.
Maybe on a single muticore but once you start talking distributed computing
(e.g. Spark which is Akka based) then all this "avoid crossing to the kernel"
optimization is becoming a drop in the ocean.

~~~
jamii
> all this "avoid crossing to the kernel" optimization is becoming a drop in
> the ocean

Here is an example of a small single threaded program beating out a number of
distributed graph frameworks running on 128 cores, with a 128 billion edge
dataset.

[http://www.frankmcsherry.org/graph/scalability/cost/2015/02/...](http://www.frankmcsherry.org/graph/scalability/cost/2015/02/04/COST2.html)

Performance matters because it enables simplicity. If your language forces you
to pull in multiple machines to solve your problem then its turned a simple
program into a distributed system and life gets complicated fast. Just
throwing more cores at a program without understanding why its slow will just
get you into trouble.

Multithreaded programs and distributed programs should be a scary last resort
after making absolutely sure you can't get away with the simple solution.

~~~
eranation
Yes I saw this, and got a little disillusioned at first, but after looking
carefully this is not big data, their entire dataset fits in RAM. When your
dataset can't fit in RAM - this is where the last resort comes into play.
Sadly most companies, I agree, don't know when data is really big data. Most
of the time it's just medium data. And I agree about the overhead costs.

~~~
jamii
> their entire dataset fits in RAM

128 billion edges. 1 TB of data just to list edges as pairs of integers. 154
GB after cleverly encoding edges as variable length offsets in a Hilbert
curve.

Do you have a bigger dataset?

~~~
eranation
Oh, I was referring to the original posts. Will take a look. Thanks!

------
ninjakeyboard
Reactive programming - you mean like reactive like reactive manifesto? That's
not event driven. See recent published manifesto
([http://www.reactivemanifesto.org/](http://www.reactivemanifesto.org/)): they
describe message driven paradigms, not event driven ones (now - this is a
revision). But that's only a very small part of it! Recommend "Reactive Design
Patterns" the free chapter from manning press:
[http://www.manning.com/kuhn/RDP_meap_CH01.pdf](http://www.manning.com/kuhn/RDP_meap_CH01.pdf)

~~~
tbrownaw
_describe message driven paradigms, not event driven ones_

Messages _are_ events.

 _Reactive programming - you mean like reactive like reactive manifesto?_

That seems to be more about idealized system properties than about a style of
programming. (Plus at least one bit of silliness, w.r.t. blocking / non-
blocking being inherently inequal.)

~~~
acjohnson55
Not exactly. Messages and events are dual to each other. Messages are sender
centric. The sender determines the links to the receivers. The receiver
listens regardless of who's sending.

Events are receiver centric. The receiver explicitly chooses what senders to
listen to. The sender fires off events without regard for who's listening.

I'm not sure how much distinction actually matters in terms of expressive
power, but it does seem to impact how the paradigms are used in practice.

~~~
Nemcue
> The receiver explicitly chooses what senders to listen to.

Not necessarily. The receiver could just specify what kind of messages to
receive instead, and be decoupled from the sender.

