jakub holý

building the right thing, building it right, fast

Example: Functional Reactive Programming decisively beats Imperative on simplicity, length

2015-06-17 14:31:30Languages

@theburningmonk Yan Cui has a nice example demonstrating how Functional Reactive Programming [slides 185 - 206] (with Elm's Signals) yields a much shorter and easier to understand (one you know FRP) code than an imperative code with mutations spread all over the code base.

The game



Use the Up and Down keys to move the platforms and thus bounce the ball from left to right and back:

screenshot-game

The imperative solution






private var arrowKeyUp:Bool; 
private var arrowKeyDown:Bool;
private var platform1:Platform; 
private var platform2:Platform; 
private var ball:Ball;

function keyDown(event:KeyboardEvent):Void { if (currentGameState == Paused && event.keyCode == 32) { setGameState(Playing); } else if (event.keyCode == 38) { arrowKeyUp = true; }else if (event.keyCode == 40) { arrowKeyDown = true; } } function keyUp(event:KeyboardEvent):Void { if (event.keyCode == 38) { arrowKeyUp = false; } else if (event.keyCode == 40) { arrowKeyDown = false; } } function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) platform1.y = 5; if (platform1.y > 395) platform1.y = 395; } }


The FRP solution




type alias Platform = {x:Int, y:Int}
defaultPlatform = {x=5, y=0}

delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows

cap x = max 5 <| min x 395 -- ^- prevent the ball leaving the board

p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input


If you have never seen Elm or a reactive program before, this is not very legible. But once you invest a little into learning, you will reap the benefits forever.

Conclusion



Imperative sucks, F(R)P is power! :-)