README.md

NoR - There's No Return.

Getting Started

So what's NoR about?, well, simply put it's just my take at what I
learned to be reactive programming yet i'm not an expert at all.

Even though the term reactive might seem like unknown, most of us
already interact with a reactive system all the time.

When you open your spreadsheet program and start using formulas that
use values from other cells, you can observe that if you change a
value in one of that cells all other cells that depend on it get
updated accordingly, well, spreadsheets are one example of
reactive programming.

If you ever played around with protoboards and logic gates, you can
recall that you used to connect all those little gates to achieve
something, say a counter, a clock or any other digital system, well,
that's also reactive, as soon as you connect all the pieces and
throw a little voltage at it, you get it to work (or not :D).

In our days, we see reactive systems all around, in recent web
development people are using more and more javascript, and as many
of us have found, front-end development is almost always enterely
event based, that is, when something changes, you have to react.
A lot of libraries handle reacting to changes, from using
jQuery to act upon a browser event, Backbone.js
and Knockout.js to bind your view and model, etc.

There's No Return

If we try to implement it on javascript, provably it would be like this:

varNOR=function(a, b){
var q =!(a || b); // just for you to see a, b and qreturn q;
}

so far so good, well, implementing the NOR gate is a trivial
program. But what happens with more complex functions that can
possibly fail, in you javascript programming, have you ever seen
functions like the following?:

varcomplex=function(some, thing){
// if everything goes fine, we return a value// otherwise the make function will just// throw an exception, how else do we handle failure?return make(some, thing, strange)
}

the bad thing about functions like this is that its users need to
know that it can possibly throw an exception as means of handling
failure, (would you really throw an exception just because some value
doesnt have the form you expected? please dont!). To fix this, most
people give the complex function a callback (or a pair of callbacks)
to be called on success and/or error.

You see? now There's No Return. All the function does is do its
amazing stuff and invoke the callback accordingly. But again as user
of this function you need to know that callback can take two arguments
and not just only one, or you can make the complex function take two
callbacks one for success and one for error. That is a callback for
each output the function can have.

How does this all relates to NoR and reactive programming?, read on.

Reacting to change

Suppose we try to implement our NOR logic gate again wihout using
return.

varNOR=function(a, b, q) {
q( !( a || b ) )
}

So now our function takes two values a and b and a callback
function q. Every time you invoke this function you give it two
values and maybe a different callback. It doenst still reacts to
change automatically, whenever the value of a or b change you
have to apply them to the function.

The logic gates (or the spreadsheet formulas) react to changes on
their input, and automatically produce a new value for them.

Now image our same NOR implementation, but this time with a and
b also being functions. These functions if given no arguments just
give you the current state of each input, and our function looks like:

varNOR=function(a, b, q) {
q( !( a() || b() ) )
}

How it works

Using the NoR function to create a gate that reacts
to changes on its inputs, and our NOR gate is:

var NOR = NoR(function(a, b, q){
q( !( a() || b() ) )
})

Looks pretty much like our previous implementation, the only
difference being that the function is wrapped with NoR.
What NoR does is creating a cell for each function parameter.

A cell is just something that looks like a function and serves to
hold a value. When a cell is given no arguments, it just returns its
current value, but when an argument is given to it, it sets its new
value and notifies everyone interested on that cell of its change.

In our example, a, b and c are cells, but only the first two are
used as inputs, the third as an output.

The return value of the NoR function also looks like a function:

; setting a = false b = true
NOR(false, true) ; => undefined

However it doesnt act as one of those functions that return values or
accept callbacks. What we have just did is simply setting the acell
to true and the bcell to false. The result of the operation is
asynchronous, that is, we cant be sure in what exact second we have the
response.

Just like with promises we have something that represents a value in
the future, we dont know exactly when, but it will hold the response
value.

So what we do for using the value of c is to listen for changes
on c by subscribing to it.

For example:

NOR.c.subscribe(function(newC){
console.log("OK, the new value of c is", newC)
})
NOR.b(false) // here we are changing the value of the b cell// sometime in the future we see// a message printed to stdout.

The NoR function form is:

NoR(gate, wiring, self)

Where gate is a function that receives cells and is invoked
whenever one of them changes. An wiring function can be specified
that receives the same cells than gate for the sake of setting up
cell subscriptions or creating inner gates. If a value for
self if given it will be wrapped on an special cell named
self and its value will be used as this whenever gate gets
called, of course changing the gate's self will trigger its evaluation.

For example, to build an XOR gate using just the universal NOR
gate, you can do:

// The universal NOR logic gate.var NOR = NoR(function(a, b, g){
g( !( a() || b() ) )
})
// the gate has no implementation as it's actually// the result of the combination of several NOR gates// and their outputs. We wire all of them on// the setup function.//// Note that the XNOR gate exposes just three ports:// a, b and q.//// However the gates wired inside use some others like// x, m and n. Follow the image above.var XNOR = NoR(function(a, b, q){}, function(a, b, x, m, n, q){
// Using the new operator on a gate// simply cretes a copy of that gate// and we assign each its ports.newNOR(a, b, x)
newNOR(a, x, m)
newNOR(b, x, n)
newNOR(m, n, q)
})

Documentation

Examples

Contributing

All contributions are welcome, of course you fork the proyect
do some changes on what you are interested, new features, typos,
tests, examples or anything you want and finally you can send a
pull request and I'll be more than grateful to you.