baconjs / bacon.js

Functional reactive programming library for TypeScript and JavaScript
https://baconjs.github.io
MIT License
6.47k stars 330 forks source link

Bacon.fix #507

Open phadej opened 9 years ago

phadej commented 9 years ago

In complex event scheduling solution on SO I run into the situation where I need fix (or loop) combinator with semantics of

Bacon.fix = function fix(f) {
  var bus = new Bacon.Bus();
  var result = f(bus);
  bus.plug(result);
  return result;
}

I'm sure that this can be implemented without Bus, and the combinator itself might be useful in the core, isn't it?

raimohanska commented 9 years ago

Will the new Bacon.repeat do for you sir? https://github.com/baconjs/bacon.js/#bacon-repeat

phadej commented 9 years ago

Bacon.repeat starts the event graph, I sometimes need to do a loop in-the-middle:

     _-f-_
    /     \
    \     /
foo----x----> foo.fix(f)

So fix semantics are: stream.fix(f) === Bacon.mergeAll(stream, f(stream), f(f(stream)), ...)

This would make possible to describe a bit more of static event circuits without flatMap.

In some sense this is a generalisation of withStateMachine as you could use fix, zip, and map to make the state machine (where the state is the event running in the loop, and zipping with new value).


Or than we could take transducers, make own implementation of Arrows (Transducers form Category / Arrows), with ArrowCircuit etc. so we can build circuits from pieces and connect them to the input EventStream:

eventStream.arrow(magicCircuit).log("awesomeness");

So those would be equivalent:

stream.map(f);
stream.transduce(map(f));
stream.arrow(Bacon.Arrow.fromTransducer(map(f)));

but expressiveness grows to the bottom.


TL;DR I seek for an elegant way to describe complex event circuits, and loopback is one we can't do, can we?