Reactor.js: simple reactive programming for Javascript
github.com
github.com
"It's the _ of Events. Too bad the symbol ~ is not allowed in Javascript."
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.)
Disclaimer: Bacon.js contributor
Perhaps my feng shui was off balance yesterday!
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.
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.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
Where does the less syntax come in? I'm looking at your signal and observer, and it looks like the same syntax as KO.
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.
http://stackoverflow.com/questions/5101113/whats-the-differe...
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-reactiveIt'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>
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.
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.
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?
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.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...