I read about FRP and was very excited. It looks great, so you can write more high-level code, and everything will be more complicated, etc.
Then I tried to rewrite my little game with several hundred slots from simple js to Bacon.
And I found that instead of writing high-level logic code, I actually beat Bacon.js and its commitment to principles.
I am facing some headache that mostly interferes with clean code
Instead of getting meaning, I have to create ugly designs.
- Cyclic dependencies
Sometimes they must be logical. But implementing it in FRP is scary
- Active state
Even the creator of bacon.js has problems with it .
An example is the world of code to demonstrate the problem:
The challenge is to prevent two players from staying in one place.
Implemented using bacon.js
http://jsbin.com/zopiyarugu/2/edit?js,console
function add(a) {return function(b){return a + b}} function nEq(a) {return function(b){return a !== b}} function eq(a) {return function(b){return a === b}} function always(val) {return function(){return val}} function id(a){return a} var Player = function(players, movement, initPos){ var me = {}; me.position = movement .flatMap(function(val){ return me.position .take(1) .map(add(val)) }) .flatMap(function(posFuture){ var otherPlayerPositions = players .filter(nEq(me)) .map(function(player){return player.position.take(1)}) return Bacon .combineAsArray(otherPlayerPositions) .map(function(positions){ return !positions.some(eq(posFuture)); }) .filter(id) .map(always(posFuture)) }) .log('player:' + initPos) .toProperty(initPos); return me; } var moveA = new Bacon.Bus(); var moveB = new Bacon.Bus(); var players = []; players.push(new Player(players, moveA, 0)); players.push(new Player(players, moveB, 10)); moveA.push(4); moveB.push(-4); moveA.push(1); moveB.push(-1); moveB.push(-1); moveB.push(-1); moveA.push(1); moveA.push(-1); moveB.push(-1);
I want to demonstrate the following:
me.positions are dependent on their own- It is not easy to understand this code. Here is a mandatory implementation. And it looks a lot easier to understand. I spent a lot more time selling bacon. And as a result, Iโm not sure that it will work as expected.
My question is:
Perhaps I missed something fundamental. Maybe my implementation is wrong in FRP style?
Maybe this code looks fine, and it's just not used to the new coding style?
Or are these known problems, and should I choose the best of all evil? So there are problems with FRP, as described, or problems with OOP.