
Reactor.js: simple reactive programming for Javascript - fynyky
https://github.com/fynyky/reactor.js
======
cmwelsh
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."

~~~
Stratoscope
"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.)

~~~
alipang
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

~~~
Stratoscope
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!

------
sinkasapa
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?

~~~
simonhughes22
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.

~~~
sinkasapa
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?

------
agersant
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>

------
judah
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>

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

~~~
judah
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.

~~~
fynyky
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.

------
oakaz
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>

~~~
geuis
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.

~~~
oakaz
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.

~~~
geuis
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?

~~~
oakaz
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.

------
sailfast
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.

------
noelwelsh
It's cool to see this kind of stuff coming out. Flapjax was way ahead of it's
time -- too far ahead it seems.

------
ncasenmare
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!

~~~
stevensanderson
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.

------
lightblade
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.

~~~
fynyky
Check out this fiddle =)

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

~~~
daok
Uncaught ReferenceError: Signal is not defined

------
baobaosaur
nice!

