Hacker News new | ask | show | jobs
Reactor.js: simple reactive programming for Javascript (github.com)
84 points by fynyky 4789 days ago
10 comments

My favorite functional reactive programming library for JavaScript is Bacon.js: https://github.com/raimohanska/bacon.js

"It's the _ of Events. Too bad the symbol ~ is not allowed in Javascript."

"Turns your event spaghetti into clean and declarative feng shui bacon, by switching from imperative to functional."

Maybe I'm just old-fashioned, but if you want to get me to try out some JavaScript library, this ain't gonna do it. Feng shui bacon? Really? How about skipping the BS and showing me some real code and compare it with the code I would have written otherwise?

(This rant is not directed at you, but at the Bacon author.)

To be fair, there are plenty of examples. If you read to the next paragraph it's in the list. There is the examples folder, as well as the TodoMVC implementation.

Disclaimer: Bacon.js contributor

I sincerely apologize for my bad attitude in my previous comment. It was uncalled-for. Thanks for not taking too much offense, and thanks for the pointer to the examples.

Perhaps my feng shui was off balance yesterday!

If you really care you could use something like window['~'].
Other than the fact that this is more minimal, does anyone have any insight in to how this compares to Bacon, Flapjax or RxJs? I've been wanting to give this coding style a try but tend to get turned off by the size and complexity of the existing libraries. I look at this as a personal fault not that of the libraries. I plan to read the source of Reactor.js, which is very well commented. Until then, does anyone know if this is a "complete" implementation or is something fundamental missing? Is it push or pull?
Bacon/Rx allows you to work with an event stream abstraction, which assigns responsibility quite differently.

Bacon is more like excel in the sense that a cell defines /itself/ in terms of other cells

    A1 = B1 + C1
or in Bacon

    var as = bs.combine(cs, (b,c) -> b + c)
The style in ko/reactor is often inverted. One opens a 'bus' or 'signal', to which an arbitrary set of others push values.

    var as = Signal()

    function bs() {
      as(...) // push value
    }
Of course, the point of Bacon is that Rx.js does not quite define an event stream abstraction, as it has the (kinda weird) distinction between hot and cold observables which can be way surprising.
Knockout does this but it also has declarative html bindings, so there is no need to do the observer logic, you just add some lightweight annotations to your html and it binds for you. I think this is a lightweight alternative to ko, but ko does a lot more and is very easy to use.
But I only want the reactive programming part. How do I take out all the parts that I don't want or need in knockout?
It's "complete" as far as I've tested it. Changes are automatically pushed out without any additional work.

In terms of how it compares - It's based off the same reactive programming principles but is trying to keep the additional syntax and complexity to a minimum.

It looks just perfect for me. And to those who keep on talking about knockout.js, this is great because not everyone wants all the bloat of yet another big "do everything" JS library.
Maybe that's just me but I think the basic example fails at conveying how this library can be useful.

http://i.imgur.com/gMuRxa0.jpg

KnockoutJS (KO) does essentially the same thing:

What KO calls observable, Reactor calls signal. What KO calls computed, Reactor calls observer.

The ReactiveExtensions library (including Rx.js) has been doing this thing for several years now, only more sophisticated than either KO or Reactor: https://github.com/Reactive-Extensions/RxJS

knockout is not FRP. Knockout uses single events, FRP uses event streams. Here's a quote from Knockout's creator.

http://stackoverflow.com/questions/5101113/whats-the-differe...

Yep. This is an attempt to do what knockout does in a simpler form with less syntax
Interesting.

Where does the less syntax come in? I'm looking at your signal and observer, and it looks like the same syntax as KO.

One difference is that there is no need to explicitly subscribe to signals. For general functions, knockout requires manually declaring "myViewModel.property.subscribe(...)" for each model you need to subscribe to. In contrast, Reactor's observer blocks automatically detect which signals you have read and sets up the subscriptions automatically.

Knockout has a different class for ko.computed vs ko.observable. For Reactor you use "Signal" for both and just pass in a function when its computed. Additionally there is no need for the trailing "this" at the end of ko.computed.

Hi, I'm also working on a minimalistic reactive programming concept; https://github.com/azer/attr

I have a library called "attr", which mixes pubsub (npm.im/pubsub) and new-prop (npm.im/new-prop)

And you simply get;

        foo = attr(3)

        bar = attr().getter(function(){ return foo() + 5 })


        foo()
        // => 3

        bar()
        // => 8

        foo(5)

        bar()
        // => 10
They are simply based on a very simple pubsub interface (publish,subscribe). So you can also do;

        foo = attr(3)

        bar = bar()

        foo.subscribe(function(update){
            bar(update + 5)
        })

        bar.subscribe(function(update){
            update
            // => 10
        })

        foo(5)
The advantage of this concept is, it's really easy to extend and optimize. Here is an example that I use new-list (npm.im/new-list) and new-object new-object (npm.im/new-object) to create some lists and objects, and use subscribe (npm.im/subscribe) module to create one callback for observing all changes:

        people = newObject({ 'jack': 23, 'smith': 27 })

        fruits = newList('apple', 'orange')



        foo = attr()

        bar = attr()



        foo.subscribe(function(update){
                bar( update + 5 )
        })



        subscribe(people, fruits, bar, function(updates){

                updates[0].params
                // => { add: { John: 21 }, rm: ['smith'] }

                updates[1].params
                // => 12

        })



        people.rm('smith')

        people('John', 21)

        foo(7)
  
My work is done until here. And here is the part that I'm actually working on: http://github.com/azer/new-reactive

It's a library for creating your own HTML binding abstractions like AngularJS. But your own that you can share, that can be extended by somebody else or can be mixed with another namespace of abstractions.

Which means, if your company is named "foo" and you're using a library called "bar", you can have bindings like;

<button foo-play="song" bar-content="i18n.play"></button>

Ok, I can follow along with your examples. But I still don't get the "why" of it. Initially it kind of seems like extra mental gymnastics and wrapping your code in an extra level of abstraction. I'm not sure what the point is.

Just as some extra background, I've read the README with the parent library this comment thread is based on. I've read the linked Stack Overflow question and answer linked from it about reactive programming. I worked my way partly through the 1998 article with the bouncing kids heads. I recently did some work with Knockout for a client. I've had some exposure to reactive programming, but I still haven't had a light bulb moment that demonstrates why this style is better.

With Knockout, I find having a variable automatically update its value interesting. I like the pub/sub concept of having a variable publish its changes to any subscribers. This is useful in many frameworks including Knockout, Backbone, and more. I think in Knockout simply executing an observable inside a function makes that function subscribe to the variable is cute. But just in my opinion, it feels like to much magic and magic is fragile.

But to ask the most pertinent question, can you provide a real-world situation of at least moderate complexity where using a programming model like your "attr" is going to be better than a more traditional way of solving it?

Thanks in advance! I'm looking forward to learning something new.

We're[1] using reactive programming in our web framework to simplify UI programming. If you've done UI programming before you know it's all about event handlers. If you have multiple inputs and outputs, and a complicated graph of what inputs affect what outputs (either directly or indirectly) then it gets extremely messy to try to track all that with event handlers. Often you end up having one big function that takes all the inputs and updates all the outputs, and trigger that big function whenever any of the inputs change--but that's inefficient if not all of the outputs would have been affected by a particular input change. None of this is a problem with reactive programming (at least not the kind of RP practiced by reactor.js and our framework, as well as Meteor which is where we drew our inspiration from).

So for us the benefits boil down to 1) almost no UI event-handler boilerplate, 2) more robust because the relationships between these different components don't have to be declared separately and can't get out of sync, and 3) much easier to do partial recalculation.

See [2] for an example that is coded up in one "traditional" UI framework, one UI DSL, and one reactive UI framework. The relationships here are very simple but you can at least see how little boilerplate you need and how much more direct the relationships between the UI widgets are.

[1] http://rstudio.com/shiny, http://rstudio.github.io/shiny/tutorial [2] http://www.r-statistics.com/2012/11/comparing-shiny-with-gwi...

Thanks for reply. The power of this concept is simplicity. It's based on a very simple API: publish/subscribe.

Anything that has these methods can be easily binded to DOM and can easily interact with data structures like new-list and new-object.

Frameworks are monopolistic. They don't let you take advantage of the open source at all. You can't replace the a core mechanism or data structure of a framework but if you use something built from small independent modules, you'll be able to optimize more, create more, reuse more, extend more, fork more.

This simplicity, the two methods interface, lets you create your own data structures that can be binded to new-reactive. Since your all dependency is publish/subscribe methods, you can easily replace each part of your code if you need to move on to another direction. But frameworks will force you to use or depend on only their own abstractions. That can be very expensive and dangerous your monopolistic framework gets out of fashion or starts implementing ideas that suck.

Ok, you're just talking about plug and play. That's a separate topic about micro frameworks. What I'm asking about is a real world example where reactive programming solves a problem better than traditional techniques.

As an example, look at Promises. At first glance it seems like overkill to structure your code to return objects that get resolved later. But when you use examples of deeply nested asynchronous callback functions and how they get cleaned up with Promises, it's obvious why they are better.

What is an equivalent real-world problem where reactive programming is better?

reactive programming is nothing except abstracting more. think about how would you define a variable and bind it to HTML. Here is my reactive way;

  JAVASCRIPT

      today = attr("Thursday")

      bind('.today', today)

      after('1s', function(){
 
        attr('Friday')

      })

  HTML

      <div class="today"></div>
      

  OUTPUT

      <div class="today">Thursday</div>

  AFTER 1S

      <div class="today">Friday</div>
This is the simplicity level I would like to achieve with minimalistic and independent modules.
I appreciate that this library focuses on being lightweight and easy to use, and I look forward to experimenting / refactoring some code with this. I'll be interested to see how this library works alongside other javascript packages for visualization and display since it doesn't have bindings - things like Knockout.js and its custom bindings always seemed rather complicated to execute, but that could've been because I didn't fully understand what was going on behind the scenes.
It's cool to see this kind of stuff coming out. Flapjax was way ahead of it's time -- too far ahead it seems.
Object.observe() is an upcoming feature for JavaScript, which allows you to add listeners to object's properties changing. With that, you could do the same thing as this library, but without this library. Still, I'm a fan of reactive programming, so thanks for this anyway!
I wish this were true, but unfortunately not. Object.observe doesn't provide any 'read' notifications, so you wouldn't be able to detect dependencies like this does.
Would be great if you can provide a simple playground app to let people try it out. It can be as simple as a github page that loads the lastest .js file into a script tag.
Check out this fiddle =)

http://jsfiddle.net/TjMgh/4/

Uncaught ReferenceError: Signal is not defined
nice!