Hacker News new | comments | show | ask | jobs | submit login
An Introduction to Reactive Programming (github.com)
455 points by staltz 1058 days ago | hide | past | web | 119 comments | favorite



I've struggled to grok FRP in the past - I hear lots of smart people trumpeting it, but I haven't been able to wrap my head around it. This tutorial was great and I was following along right until it got to the part about modeling the suggestions as streams (https://gist.github.com/staltz/868e7e9bc2a7b8c1f754#modellin...).

That was where everything went haywire for me - my brain doesn't want to think about those UI elements as streams and I instantly tune out and think "this doesn't make sense". I'm curious if anyone else also got stuck at that same part, as well as if anyone has suggestions/ideas for breaking past this mental barrier? Is there a different way of solving the same problem (that might make more sense to me)?


You can think of an animation as a stream of frames; this is how video is implemented. It especially makes sense for video games that typically have a game loop that renders the screen at 30 or 60 frames per second.

Similarly, a UI element can be thought of a a stream of snapshots. Each time you render the UI element, you're creating another frame.

In Elm, an entire UI is a stream of frames. (The type is Signal Element.) When you put Elements together into a tree, you're just constructing a single frame of an animation.

Unfortunately, a UI in Elm is not composable in the same way as a traditional UI. The model, appearance, and behavior of a UI element are handled by different parts of the program. This is sometimes good (model and appearance are cleanly separated) but it's unclear whether we can build large applications this way. It's one of the reasons why Elm is still an experimental language.


Hmm, this sounds like immediate-mode GUI that is a well known design in games. Since games people are used to rendering the view anew on each screen refresh, it was logical to do this for widgets as well.

See eg. https://mollyrocket.com/861

edit: and of course I was hardly the first one to make the connection :) Long IMGUI discussion at http://lambda-the-ultimate.org/node/4561 with 20+ mentions of FRP.


Immediate mode UI is more continuous (refresh every 15 ms) and not stream-based, which is actually quite different from Elm and is more like React.


> my brain doesn't want to think about those UI elements as streams

The UI elements themselves aren't streams. Also, you're missing an important keyword--they're "event" streams. Stream in this context just means an ordered set of momentary events occurring in more or less real time--a button was clicked, the server responded, a sensor reading was taken, an item was purchased, etc.

In order to get a good understanding of FRP, it would probably first help to understand laziness as found in Haskell or .NET IEnumerable/yield return or Python's generators, etc. The gist is that you have a function that can return a value and then effectively pause it's execution until you call it again. A simple example is an infinite counter: the first time you call it, it returns 1; the next time it remembers that it had previously returned 1 and so it adds one more and returns two, etc.

Usually when this kind of laziness is considered, it's the job of the calling code to say, "I'm ready for more data" and then 'pull' the next chunk. In FRP, this is reversed--the client/calling code says, "let me know if/when anything interesting happens" and the stream 'pushes' data to the subscriber. The functional part comes into play when you start manipulating the pulled or pushed data by specifying functions as arguments to the 'higher-ordered' functions that work on the data. I.e., when we get the data, do this() to it and then do that()--where 'this' and 'that' are variables/function-pointers.


Why not try watching the video from Jafar Husain, a tech lead from Netflix, talk about Async JavaScript at Netflix which uses RxJS to explain these concepts? https://www.youtube.com/watch?v=XRYN2xt11Ek


+1, I've seen this talk, very approachable.


I was struggling with the way the operators are written:

  clickStream.map(f).scan(g);
Then I realised that map() and scan() are not doing much when that line of code is executed. They only add a new operation step to a list of operations for clickStream. Only when an event is received, the saved list of operations gets executed. So, I think a better naming would have been addMap() and addScan(), because they only add operators. They don't map/scan anything when they are called.

I think the best tutorial for me would have been an article explaining what is going on under the hood. This tutorial does mention this implementation detail but only very briefly.

Anyway, without the tutorial, I wouldn't have realized this, so it was actually helpful. :)


Streams are lazy. They work in the same manner as lazy collections in languages such as Scala and Haskell - if you have an infinite collection, say, the set of all prime numbers, and do a map operation on it, it does not try to eagerly execute an infinite loop. Instead, the mapping is only done when when you actually request any of the elements of the set.


> So, I think a better naming would have been...

Often I like to use past participles as names for stream or signal combinators.

So instead of `map`, `filter`, `fold` -- the names are `mapped`, `filter`, `folded`.

For example, given a stream, `(mapped stream f)` returns a new stream with f mapped over it. It returns a mapped stream.


When working with functional programming, thinking about "doing" is often the wrong approach, because "doing" is often tied to "change of state". Instead, think about translations/transformations from "what I have" to "what I want".

clickStream.map(f) doesn't "do" anything - it takes a stream, and returns another stream that's the result of f applied to each element of clickStream.

So if I do something like: astream = clickStream.map(a) bstream = clickStream.map(b) cstream = clickStream.map(c)

I've created three streams that are each the result of a particular function applied to the elements of an original stream.


You can try our Learn RxJS tutorial here as well: http://reactive-extensions.github.io/learnrx/


"add___" might imply mutation of the stream, which it seems to me (just reading this tut for the first time) isn't the mindset the framework wants you to be in.


I came to FRP in a functionall language (Haskell) so I am not sure how applicable my experience is.

Often, you can treat the stream element as an implementation detail. Where possible, you simply define the state of widget A to be a function of the state of widget B. Keeping in mind that this is implemented in terms of streams will tell you what function to use to make this specification. In this line of thinking, I often think of the system as a static network, where each node (representing a widget) is a pure function converting some inputs to output (or has no input and produce a constant output). A widget can also set its appearence based on its input.

When the user provides input to a widget (in this model), the corresponding node itself changes to produce a different output (giving you a new, static, graph). For simplicity, I will assume that all user-input widgets correspond to output only nodes.

For example, consider a netwwork, X, with node A corresponding to a textbox. A takes no input, and outputs the constant of the current value of the textbox. Imagine that we know what the value of the textbox will be at all times, and want to animate the entire window. To do this, we can stream in the values of the textbox, and let the network update itself. In this way the textbox is sending a stream of strings into the rest of the network.

Moving to a lower level, consider how the textbox itself is implemented. While we can think of it as output only (as I almost always do), it can be implemented as taking a stream of key-events, and outputing a stream of strings. At this level, I take an event driven perspective. While the textbox recieves a 'stream' of key-events, and outputs a 'stream' of strings, what really happens is that whenever there is a key event, the textbox receives it, and emits a string event, in the same way that you might have an onEvent() handler call onStringChange() in a traditioanl OO design.

In writing this, and re-reading your question, I think the key difference is that I do not view UI elements as a stream. Instead they are static object that streams pass through. As streams pass through them, they be update the stream or themselves.


Hi, can you make that question on the gist so that the discussion persists there? I'd be glad to try to fill in the missing mental bits there.


Sure thing :)


Many claim that reactive approach somehow makes thing easier, to me it just looks like a solution (not really) in search of the problem. So for now I just dismissed it as a fad. Will see.


It's not a fad at all, with Netflix and other companies using Rx in all flavors on their platforms. See this video from Jafar Husain, a tech lead at Netflix, talk about how they use RxJS at Netflix: https://www.youtube.com/watch?v=XRYN2xt11Ek


It is possible that I am wrong, but I Netflix using it does not necessarily proves that it is not a fad.


Ok, the consider GitHub for Mac and Windows are both written using Rx frameworks. In addition, so is Cortana from Microsoft and has been in the phone ROM since day 1


FWIW I don't think FRP is a fad, but big companies have lots of projects going on all over the place and it isn't uncommon for an engineering team to be given permission to trail some tech, especially at an OSS shop. Netflix might have some team(s) using some Brand New Library but that isn't sufficient evidence for that tech not being a fad. Switching costs are high at companies that remain in business and are growing so it's not uncommon for a big shop to have some random tech written in fad code that people absolutely despise in the future.


If Netflix uses it, it must not be a fad! Silverlight is poised to take over the WORLD!!!


I thought this was a decent tutorial, but I'm a bit annoyed at the double-click bit. Yeah sure, you can implement some form of double-clicks in 4 lines of code, but it behaves badly. And since the tutorial glossed over it, I have no idea if this is just because the author doesn't realize they implemented a really bad click system, or because it takes a lot more than 4 lines of code to do it right and the author didn't like that so chose to ignore it.

Notably, the single-click stream has a built-in 250ms delay before the click is fired. That's bad. Similarly, the double-click has a built-in 250ms delay even if the user clicks twice within 100ms. In fact, it's not just a 250ms delay from the first click; it's a 250ms delay from the last click before it finally emits the event.

That's a completely unusable way of doing clicks. If that's how you do clicks in FRP, then that's a serious issue with FRP. I have to assume there's a better way, and I'd really like to see it.

The correct behavior is to emit a click event immediately upon a click, but to remember recent history and associate a click count with the event based on whether there are recent clicks. So if I click 7 times in a row at sufficient speed, I should get a click event for every single one, getting 1x through 6x clicks before finally getting the 7x click on the last one.


Sure, you can do that. If it's not how you want it to be, just tweak it. http://jsfiddle.net/staltz/U2j4D/8/


Interesting implementation - I'm just starting to poke into reactive, things like this help me think differently :)

That said, this is not the same thing as a double-click handler. This is a single click plus a double click when you click twice. Typically when you do double-click handlers you delay single-click until it's a confirmed not-double-click. I think I have an idea of how to make that work here, but do you have a preferred approach?


Thank you, that behaves a lot better. It seems a bit odd that the multiClickStream emits a `0` 200ms after the last click, but I guess you can add the filter to the multiClickStream directly and let the button clear its own text a different way.

http://jsfiddle.net/U2j4D/17/

So more than 4 lines of code, but I'm glad to see it's quite doable.


I am writing a game engine in Scheme that uses FRP. My implementation may not be robust since I'm the only user, but perhaps seeing what it can do will help someone. My implementation was heavily inspired by Elm.

Blog post with screencast to demonstrate:

http://dthompson.us/functional-reactive-programming-in-schem...

Implementation details:

https://gitorious.org/sly/sly/source/8cf0096791821c7711c9dc2...

2048 clone written in a reactive style:

https://gitorious.org/sly/sly/source/8cf0096791821c7711c9dc2...

Reading the explanation from the Elm folks is what made things click for me:

http://elm-lang.org/learn/What-is-FRP.elm

Edit: Also, SICP has 2 sections that describe systems that are reminiscent of reactive programming systems.

A Simulator for Digital Circuits:

https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.htm...

Propagation of Constraints:

https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.htm...


Why not look at Gregory Cooper et. al.'s FrTime? Its the first FRP system I'm aware of for Scheme, and its quite well used in Racket. It is also a predecessor of Flapjax.

http://docs.racket-lang.org/frtime/


I've read some of this source, too. Thanks.


Names can change over time but here is how i recall it:

FRP is a development based on the work of conal elliott: http://conal.net/ It's main characteristic is that there is a continuous (pull)aspect. Since many interesting domains are not predominantly continuous he and many others had to add a discrete event based component.

Rx is a stream based technology (push). Basically it is a dataflow library with modern functional programming syntactic elements. It does not have a continuous aspect and as such it is not FRP.

By treating Rx as something new we are depriving our self of the dataflow and structured programming knowledge.


Here's an introduction to Bacon.js, implementing a game with eventstreams, if anyone is interested in more.

http://philipnilsson.github.io/badness/


A lot of people have reported that they grok Rx* much better once they watch this talk I gave at http://vimeo.com/43659034 - if you understand map / reduce / filter as applied to lists (in C#, "Select / Aggregate / Where"), Reactive Programming isn't too hard to understand if properly explained.


This was also a good eyeopener, from the man himself:

http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Key...


Rx isn't really reactive programming so much as slinging event streams around, there is much more to reactive programming than that (e.g. ReactJS is based on something completely different).


Before we launched React we had a big discussion as whether we should change the name or not. React is completely different from everything that's called "reactive programming" and we were afraid to cause confusion.


I personally find it causes a lot of confusion. Generally the term "reactive" has become very buzzwordy and meaningless if late. I think Meijer's talk just touches on the beginnings of it.


I know the stream based RX and several continuous/events based FRP implementations and their associated problems.

Are there other interesting approaches?


Well, there is also managed time.

http://research.microsoft.com/apps/pubs/default.aspx?id=2112...

Constraint and logical systems like Bloom also qualify in dealing with change (the underlying meaning if "react"). The nice thing about FRP was that it went way beyond event streams, which is why Rx is so disappointing (which is just about event streams, react + Rx is sort of FRP).


I think my general feeling is that "there is no true reactive", but it's trendy to be responsive in that you have a system which behaves in soft or hard real time. There are a lot of components of such a system and lots of ways to organize it, but no clear feeling for which is best.

At the end of the day it always feels like fighting between general purpose programming languages. Nobody can win, everyone optimizes for different things, and broad terms are useless except for marketing.


I always have to stop and check which 'react' something is talking about lately every time.

From my perspective it is causing confusion...and I don't think I am alone.


It's funny how people think Reactive is new as we've been around since 2007 in different forms with a big release back in 2009 (so five years ago).

I would disagree as being the primary author of RxJS as well as a contributor to all other flavors that it's just about slinging around events. It's more than just that as we have to deal with failure, load, etc.


Basically, Rx was a huge step back from FRP by getting rid of behaviors and focusing just on events. So ya, you get to do things about those streams, but none of the fancy continuous binding computations that could be done in FRP (and to a lesser extent, React).


Can you give some examples? I'm failing to see how this was a step backwards.


The classic one would be C = A + B where A and B change continuously over time, causing C to change continuously to match the current values of A and B. Change propagation then becomes a core part of push-based FRP (pull based with just resemble), whereas in Rx you have to manage the change streams for A and B manually.


C = A + B in Rx is just a combination of 2 observables. One way of doing that is with "combineLatest":

    A.combineLatest(B).map((a,b) => a + b)
Of course, you may want to cache the last emitted value for "a+b", or a default value in case no items were emitted yet, something that would be a hot multicast observable, roughly:

    A.combineLatest(B).map((a,b) => a + b)
      .multicast(BehaviorSubject(default))
And the underlying framework can optimize for this use-case, with shortcuts and whatnot. In Scala, nothing would prevent you from having a sexy macro, akin to Scala-Async.

All that matters is the underlying abstractions are Observable (the producer, characterized by its subscribe method), the Observer (the consumer, which is really a single function split in 3) and the communication protocol between them. I don't see that as a regression, I see it as the foundation - in the end, no matter what you make of behaviors, it's still a producer/consumer pattern.

Actually my problem with the original Rx implementation is very different. I'm also working on an Rx redesigned implementation for Scala, with back-pressure baked in by design in the protocol [1]. This is because when events are passing asynchronous boundaries, you can have streams that are producing more data than consumers can process and (compared with other abstractions for processing streams of data, like Iteratees) the consumer doesn't signal demand back to the producer. And this issue becomes even more relevant when events are sent over the network.

[1] https://github.com/monifu/monifu/wiki/Rx-Contract-and-Design...


Right. You do it yourself in Rx, including the topological sort needed for glitch-free re-evaluation and whatever other features you need. Is there is a meta protocol to dissect event streams to reason about there sources? How does switching work? If you read an FRP paper, say Leo's flapjax one (which is still only kind of FRP), you see all the complexity needed to support those features; no wonder Rx didn't bother.


There were definite tradeoffs to make while we were designing Rx and that was certainly one of them. Since we don't want to have to check if the stream is the same stream, instead of saying:

stream1.combine(stream1.skip(1), ...)

We encourage since it is the same stream to use zip to avoid glitches and keep our overall memory footprint low:

stream1.zip(stream1.skip(1), ...)


I've asked about back-pressure before here with regards to Rx - this was the response: https://news.ycombinator.com/item?id=7889968


That information is a bit dated as we have several ways of dealing with backpressure starting with RxJS 2.2.15 with the inclusion of pausable/pausableBuffered and controlled https://github.com/Reactive-Extensions/RxJS/releases/tag/v2....

We then updated it to have .pause and .resume methods on the Observable itself to take care of some of the ugliness: https://github.com/Reactive-Extensions/RxJS/releases/tag/v2....

Overall, these do not go ultimately up to the publisher as we're dealing with multicast streams in which we don't want other subscribers to pay any penalty for one slow subscriber.


interesting, thanks!


This is super helpful. The example with the multi-click stream is pretty impressive as a demo. Is anyone familiar with the Elm[1] language/library that compiles to JS? Does it facilitate good FRP practice? Or are there any better libraries/languages out there? I've just seen a lot of Elm when I've google FRP in the past. (Followed closely by Haskell.)

[1] http://elm-lang.org/


Neither Rx nor Elm are FRP. If you want FRP, look at Conal Elliott's work.


I haven't looked at Elm deeply, but last time I took a look it seemed to be very much FRP. What do you think it is missing?


This pedantic distinction isn't useful to anyone, please stop Well Actually'ing people


It's not a pedantic distinction given how much the term has been overloaded to refer to dissimilar concepts.


We should just have separate terms for Discrete vs Continuous flavors instead of fighting over the one true "FRP"


It's not just that. Elm and Rx lack continuous value streams at all, they are completely discrete; also they are very much asynchronous, so they are more like the event stream manipulation done via data flow in the 70s rather than what Elliott and Hudak invented in the late 90s.

For something to be called FRP, they at least need both continuous and discrete abstractions; the simplest description of FRP involves re-evaluation A + B over time, which is not meaningful in Rx or Elm, really.


It's meaningful in Elm.


I would love to see an example. I've browsed Evans' thesis, and it seems like he explicitly avoids continuous abstractions (behaviors) for event processing.


Here is an example: http://elm-lang.org/edit/examples/Reactive/Position.elm

In Elm behaviors and events are the same thing. Usually operations like filter and fold are only on events, and applicative functor and monadic operations are only on behaviors, but in Elm one type support filter and fold and the applicative functor operations, and monadic bind is not supported at all. I don't think that's good design, but it does mean that Elm has the functionality of both events and behaviors.


Will do. Thanks for the pointer. Do you have any suggestions offhand?


Start at the beginning:

http://conal.net/fran/tutorial.htm

Warning: FRP is much more purest than Rx (which is just data flow) or Elm (which is more FRPish but asynchronous). You probably don't want FRP but something more pragmatic like the fore mentioned systems.


From what I understand, although Conal Elliot coined the term FRP first in a relatively narrow sense, today the term FRP is used much more freely to describe reactive programming using functional building blocks (especially combinators like map, filter etc.).

There are some nice papers that give an overview of the FRP landscape.

“A Survey on Reactive Programming”: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.416...

“Towards Reactive Programming for Object-oriented Applications”: http://www.guidosalvaneschi.com/attachments/papers/2014_Towa...


This is not true at all. It is only recently and only in the SF hacker bubble that FRP has been co-opted to mean anything that is functional, reactive, and programmed.

Outside, FRP still means FRP, and using the term will automatically put your work in a certain specific bucket that you might not want to be in.


These papers actually look readable. I'll give them some time, thanks for posting!


Elm nor Rx or any of its variants are FRP, and instead, we like to consider ourselves on the Rx team as complex event processing and stream-based programming.


Would you elaborate on why Elm isn't FRP please? I've added a bit, but I hope to hear more from an expert on the topic :)


My buddy held a talk on Elm last week and they're going to publish a paper on it focusing on the FRP part. But to my knowledge Elm isn't pure FRP because it mixes state with behaviour. (not entirely sure though). The good part is that it works, the bad part is that it's creating messy and bloated js output, even for hello world.


With seemingly more emphasis being placed on complex pub-sub architectures, has there been any equivalent development of tooling to assist in visualizing/grokking an existing pub-sub application? In my experience at least, pub-sub architecture can be difficult to follow without good tooling (trying to keep all of these coexisting streams in your head when making changes, as asynchronous code is difficult to write a test suite for that could catch mistakes). This is somewhat just the nature of asynchronous programming, but there has been more and more emphasis on that as well with the popularity of highly responsive GUI applications and more computing capacity for background tasks.

Aside from using Visual Studio-esque "find references" to navigate to all of the locations in a codebase where a particular event stream is subscribed to, I've yet to come across much.


It looks to me like Bacon.js is the community favorite and RxJS is the corporate framework when it comes to JavaScript libraries for FRP. I'm thinking about introducing an FRP library into the frontend stack where I work — does anyone have any experience with using either of these libraries (or another) for corporate work? What did you use and how did your coworkers deal with it?


As the primary author of RxJS, I take exception to that characterization. Anyways, you should look at the performance differences between RxJS and Bacon.js. They are quite significant! https://github.com/pozadi/kefir/blob/master/test/perf/memory...


Hi Matt, fyi the codeplex page doesn't mention what appears to be the primary website: http://reactive-extensions.github.io/RxJS/ so you might want to get a link added....


I should be clear that I'm only referring to the superficial characteristics about the frameworks. Nothing about the API itself seems very corporate. Thanks for the pointer to the performance characteristics. I'm interested in differentiating factors.


I also found Martin Odersky's Principles of Reactive Programming Coursera class [1] very helpful.

[1] https://class.coursera.org/reactive-001


I and a friend attended to the class and read several papers, but all you learn are concepts, tools, paradigms and implementations. There is no "formula" for creating FRP, it's very generic although highly specific on monads, (applicative) functors, monoids, etc. So definitively worth a shot, if you want to learn everything around FRP.


Great article but there's something I'd like to understand: the article talks about FRP yet writes "(Functional) Reactive Programming" with "functional" between parentheses, why?

Is the 'F' in FRP the same 'F' as when people say that, for example, Haskell and Clojure are FP languages?

Does FRP use the notion of "functions" which are closer to the mathematical definition of a function? For example does FRP try to avoid state and mutable data as much as possible and do the same inputs always lead to the same output? Or is it called "functional" simply because it allows to use things like map/reduce/filter?

If it is "really" functional, I take it it's quite deterministic: can you then take all these streams of events and "replay" them at will, always ending up in the same intermediary state and, eventually, in the same final "state"?

If that's the case, then it's the next thing on my "to learn" list :)


> There's something I'd like to understand: the article talks about FRP yet writes "(Functional) Reactive Programming" with "functional" between parentheses, why?

This comment https://gist.github.com/staltz/868e7e9bc2a7b8c1f754#comment-... and this discussion https://twitter.com/ReactiveX/status/483625917491970048

> If it is "really" functional, I take it it's quite deterministic: can you then take all these streams of events and "replay" them at will, always ending up in the same intermediary state and, eventually, in the same final "state"?

Yes. See this http://debug.elm-lang.org/


We use ReactiveCocoa [0] extensively at work and can't recommend it highly enough [1]. (Although admittedly KVO makes Cocoa almost the ideal platform for reactive programming.)

[0]: https://github.com/ReactiveCocoa/ReactiveCocoa [1]: http://ianthehenry.com/2014/5/4/kvo-101/


If you're interested in FRP in terms of GUI programming, as described in the linked article, you should definitely checkout ReactFX [0], an FRP library for JavaFX, and also the author Tomas Mikula's blog [1] that contains very convincing examples of FRP's usefulness for real UI tasks [2].

[0]: https://github.com/TomasMikula/ReactFX

[1]: http://tomasmikula.github.io/blog/

[2]: http://tomasmikula.github.io/blog/2014/04/25/combining-react...

If you are confused by the term FRP and its different interpretations, I tried to summarize them in a stackoverflow answer: http://stackoverflow.com/questions/22795062/is-it-possible-t...


Lee Campbell's book/site is a good place to start - http://introtorx.com/


Some additional overview of different reactive approaches:

http://www.slideshare.net/deanwampler/reactive-design-langua... https://www.youtube.com/watch?v=4L3cYhfSUZs

* responsive (somewhat hand-wavy - basically, don't block on IO)

* scalable (hard to be scalable - many different approaches)

* resilient (hard to be resilient - erlang is king here)

* event-driven (it's hard to not be event-driven these days)


The Reactive Extensions covers all of those particular topics quite well, in terms of responsive to failure, responsive to events, responsive to load etc.

We cover that a bit in our repository with the Reactive Manifesto: https://github.com/Reactive-Extensions/RxJS

And I've even covered it at StrangeLoop 2013: video: http://www.infoq.com/presentations/rx-event-processing slides: https://github.com/Reactive-Extensions/StrangeLoop2013

As well as FutureJS: video: https://www.youtube.com/watch?v=zlERo_JMGCw slides: https://github.com/Reactive-Extensions/FutureJS


> FRP streams go beyond promises by allowing many returned values. This is pretty nice, and shows how FRP is at least as powerful as Promises.

The fact that you can only return a single value from a promise is a feature, not a limitation. In synchronous code, you can only return once from a function. In asynchronous promise code, you can only fulfill the promise once. There's a parallel.

If you want to "allow many returned values" you can just use a callback. You hardly need a "stream" for that.


> In synchronous code, you can only return once from a function.

Erm, have you heard a term "continuation" or "call/cc" ("call-with-curent-continuation")? Or "delimited continuations"? Or maybe even "Cont monad"? You should read on them, if you haven't - they are one of the most fundamental and fun concepts I encountered.

But even without those, what you wrote here is false in the presence of generators (which are coming to JS any day now!).

I'd say that returning more than once from function is actually a pretty basic technique which is widely used to implement quite a wide array of different things.


Or, over in C land, setjmp.


A stream can be thought of like a function in a lazy language returning an array of results which aren't necessarily calculated (or available) all at once.

>If you want to "allow many returned values" you can just use a callback. You hardly need a "stream" for that.

Callbacks are hard to compose, may not have standard error conventions, and you can't have multiple listeners subscribe to the same thing after the fact. (Those are the same things that promises solve for async functions with a single result.) Additionally, you can stop listening to a stream and the source can know to close itself once it has no more listeners.


For those searching for Rx examples, I found these:

https://github.com/fdecampredon/react-rxjs-todomvc (TodoMVC implementation built on top of React + RxJS)

https://github.com/eliseumds/react-autocomplete (React + RxJS Autocomplete)


Yep, there are plenty of examples to be found such as those listed here: https://github.com/Reactive-Extensions/NDC-Oslo-2014

In addition, we ship a good number of samples within our RxJS repository: https://github.com/Reactive-Extensions/RxJS/tree/master/exam...


Cool!


If you want to learn streams the hard way try to implement any non trivial build process with gulp.js

Just a warrning. Node.js had 3 versions of streams so far and some packages that implement stream functionality don't all work properly with latest version. Also two types bytestream and object stream.


Node.js streams are largely unicast, instead RxJS and related libraries can be multicast. RxJS, on the other hand has been fairly stable for quite some time now and the APIs largely haven't changed from when we first released in 2010.


To add another resource to the list, I gave an introductory talk to bacon.js and FRP last year which has similar diagrams to these which I animated with d3 if anyone'a interested: http://vimeo.com/m/68987289


I wrote a little FRP library in Ruby: https://github.com/steveklabnik/frappuccino


steveklabnik, still working on the Ruby port of Rx. It will get there but needs more community support.


RxJava's wiki is also pretty good: https://github.com/Netflix/RxJava/wiki


How is this different from complex event processing (CEP)? High frequency trading has been using this from day 1.

The real trick is working with historical events and fetch them from disk, otherwise your reasoning time window is restricted to whatever fits in RAM.


Using Rx, you can certainly do CEP as we have buffer and window operators, and the ability to so groupBy and other complex operators. For example we have one that analyzes stock streams https://github.com/Reactive-Extensions/NDC-Oslo-2014/blob/ma...


So, are you saying Rx is the superset and CEP is a subset of Rx functionality? What can you do in Rx that you can't do in CEP?


I would certainly say that Rx has a superset of the operators in standard CEP which largely deals with buffers and windows, yes. In addition, we have time-based join and group join behavior, join calculus eg: Rx.Observable.when( stream1.and(stream2).then(...), stream3.and(stream4).then(...) );


There is one thing that really bothers me, I've not found a single a mathematical formula that defines FRP. The closest thing I've found was the "Denotational Semantics" showing the logic behind, which is quite lenghty and leaves a lot of room for variations. I hate descriptions full of buzzwords that, when you look at it closely have really nothing to do with FRP, but are mere tools that help realizing it.

Is there someone who can explain us scholars how FRP can be noted down formaly? Even a link to a page of a paper that shows the formula would be enormously useful. I'll put all the good papers that I've found in the footnoes.

--------  The following are a few of the good papers on FRP (ordered by subj. quality). I've read the Elm paper, but it's vague despite having a lot of maths in it. What it really decribes is not FRP, but Elm (also it's not exactly FRP).

 [1] https://blogs.janestreet.com/breaking-down-frp/  [2] Higher-Order Functional Reactive Programming without Spacetime Leaks - https://www.mpi-sws.org/~neelk/simple-frp.pdf  [3] An Axiomatic Semantics for Functional Reactive Programming - http://www.wpi.edu/Pubs/ETD/Available/etd-042908-133033/unre...  [4] Push-pull functional reactive programming - http://conal.net/papers/push-pull-frp/  [5] Categorical Semantics for Functional Reactive Programming with Temporal Recursion and Corecursion - http://www.cs.bham.ac.uk/~pbl/msfp2014/catsemfrp.pdf  [6] Completeness of Conversion between Reactive Programs for Ultrametric Models - http://www.cs.le.ac.uk/people/fdv1/fdv1/Distribution/SeveriD...  [7] Fair Reactive Programming - http://www.cs.mcgill.ca/~acave1/papers/fair-reactive.pdf  [8] A Survey on Reactive Programming - http://soft.vub.ac.be/Publications/2012/vub-soft-tr-12-13.pd...  [9] Signals, Not Generators! - http://www.ioc.ee/~wolfgang/research/tfp-2009-slides.pdf  [10] http://stackoverflow.com/questions/5875929/specification-for...  [11] http://stackoverflow.com/questions/1028250/what-is-functiona...

The bad thing about all those papers is that a) you need to know Category Theory, b) Temporal Logic, c) Denotational Semantics d) (and optionally Henkin and Ultrametric Models) Unfortunately I'm not yet that smart :( hope someone can bring clarity into FRP

Sorry for the ugly footnote, that's the best I got using HN's formatting capability.

Update: I used unicode spaces, that fixed it.


Push-pull is one of my favorites, but it's pretty "operational".


"Javascript is the most familiar language out there at the moment"

Will people ever stop using this reasoning? Why not pick the best/better language instead?


Because the goal here is not to write the most efficient and most maintainable code, but to demonstrate a new concept. Familiarity and availability are more relevant in this case than "best language," however you'd measure that.


Hmm. Java might be known by more, if just from the fact that those who take an introductory CS course as an elective in another major will get their lessons in it. But, as a lingua franca, it sucks even worse.

Mind that term, actually: while French itself was just an average European language, it was handy, for political reasons, for diplomats of all stripes to pick up—and somewhat easy, presuming you had studied texts in Latin. JS is much the same: a lot of us might not prefer it when writing our own code, but we can all certainly read it, given its ALGOL derivation, and it's certainly more pithy than, say, C, for communicating the kind of concepts we need to communicate (like FRP.)


> But, as a lingua franca, it sucks even worse. Mind that term, actually: while French itself [...]

Mind that term even more, because despite the similar "fr--" sound, it does not actually denote the French language.

"Lingua franca" is actually an Italian term for "Frankish language", during a time (post-middle-ages) when "Franks" often referred to Western Europe in general.

While French is an example of a language which fit the definition for a period of time, it is not the source of its name.


There is a lot of sense in it.

First, most everybody has a JS engine handy, right in the browser of his choice. JS is reasonably standardized - the subset of it which is common between all browsers is pretty big. Then, JS is rather well known, since all web development has to include that - and that's a sizeable part of all development. Next, the language itself isn't that bad - you may write procedural, object-oriented or functional code relatively easy. Even better, the implementations are quite good lately, being forced to evolve under the pressure of demand.

Can you name a language which would best JavaScript in all these points?


  > Can you name a language which would best JavaScript in
  > all these points?
Why language has to best javascript in all these points? What's the point? Why should I want to write procedural, object oriented or functional code in the same language? Why not choose a language that fits a task at hand instead of being "quite good" or maybe "not that bad" and "rather well known"? Javascript for everything is at the same level of moronism (and subset of) webtech for everything. It just does not make any sense.


Well I think in this case the language does fit the task at hand, since the language choice is one of communication (communicating concepts), it's probably a wise choice to go with a ubiquitous one to achieve the goal of delivering a message to the widest possible audience with the least friction possible.

I don't know if English is better or worse than Lithuanian, but none of that probably factored into your decision to speak English here rather than your mother tongue. Like many of the other non-English speakers I see on HN, I don't assume you are saying English is a superior language, rather I assume it is that you see as English is the lingua-fanca of the world currently, you want to lower barriers to understanding your concepts and communicate to the widest audience possible. If that is why they chose JavaScript, then to me, that's a rational choice.


Then this paper might be of great help to you

http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR201...

It's straightly viewn from an implementor's perspective in my opinion.

Tl:Dr.: The observer-pattern is bad and encourages callback-hell, therefore a Data-Flow DSL is implemented to control the order of evaluation. It's kind of showing the implementation of an IO-Monad.


He is right.Everybody has a browser, where one cast copy paste code ,execute it and see the result.

Not sure what the alternative would be.Python/C/C++ on linux maybe.

But on Windows? what language does Windows support from scratch that Linux supports?

And since everybody knows Javascript... Not saying I like the language but it became easy to explain something in a language everybody can read through js.


Because in this case, RxJS is actually quite easy to explain because of the lack of generics and angle brackets to get in your way to explain concepts. (Speaking as the author of RxJS).

That and it's very applicable to current problems with web-based programming of the coordination of events, promises, and any other I/O such as Web Sockets, XHRs, etc.


It's BASIC of new generation(s).


So what is its GOTO?


In Bacon.js it's the Bus. I'm not sure if RxJs yet has such thing :)


Agreed.


> So you're curious in learning this new thing called (Functional) Reactive Programming (FRP).

Chaining is the new goto. Abused, it causes deeply anti-modular, temporally coupled code, which is really really ugly to maintain (good thing rockstar ninja programmers only need to think two weeks ahead).


You are confusing "chaining" with "composition". The two have fundamental differences. This confusion is understandable though because languages without a strong type system make true composition very loose (the exception being stack based languages, I think).

Javascript is a poor language for composition; stream programming is uniquely suited to strongly typed languages with denotational semantics that make function composition natural and you'll probably be seeing much more of Elm and other Haskell to Javascript compilers taking the stage for this.


Reactive programming (languages) are supposed to give you a way to deal with such complexity, for instance by solving the inversion of control problem. This really is not chaining events together, just as structured programming is not just chaining todo's together.


In this case, it's no more abuse than Ruby's Enumerable, JavaScript's Array#extras, and of course .NET's LINQ. How is this abuse exactly?




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: