On Functional Reactive Programming…
FRP has been getting more and more attention lately in different areas of our industry, with good reason, it’s a tool that wasn’t obvious before.
Skipping that discussion, let’s talk about how we think about state. You try and design your models as immutable structures, right? This means state is fixed. If you want to mutate something, you create a new thing by copying and update the state before you return that copy. Alternatively you create a whole new thing with the data you want changed at the time of creation. It’s the same thing, just an implementation detail.
If you model your data as mutable structures, let me reserve judgement for the moment and just say that for all you know, a changed value has been that value since the object was created. You don’t know when it changed, or at least if you did, you’ll forget at some point. This usually leads to bugs.
I want to take an example of a car, as a piece of state. Let’s model it. A car has a frame, it’s got a body type, a body colour, some wheels of a specific size, shape and appearance. It’s got windows on the sides and the front/back. It probably has a trunk, an engine, a gas tank, seats, ignition, steering wheel, gas pedal and break pedal, as well as a driver at a minimum. There are lots of pieces of state in a car. How much of it changes? Let’s address the obvious items:
- If you have a flat tire, you need to change it
- If your tire has a lot of wear, you need to change it
- If your windshield cracks, you need to change it
- If your breaks stick, they must be repaired
- If you run out of gas, you need to add more
- If you lend your car to your brother, it has a new driver
So on, so on… One thing you’ll quickly notice when you stop and think about modelling a vehicle is, all the things that can effect your state, can themselves be modelled as a stream of events. Also, the pieces of your vehicle themselves generate streams of change events, whenever something happens to them. All of a sudden, we’re not modelling state so much as we’re modelling the actions that occur on subjects. The actions represent the state changes across time, and we, as an observer of the vehicle, can see these changes as they happen. Our model is reactive.
This brings up another fun point, if we start viewing state as time-varying variables, how can I apply transformations to this data, i.e., when its read?
What if we thought of streams as infinite lists? Lists we could apply common techniques like enumeration, folding, filtering, mapping, all of a sudden these streams are becoming more and more useful as we introduce regular concepts we use daily even in the imperative world.
The key takeaway here is that the first impediment to understanding FRP is not to change the way you write your code, not at all. But rather, instead of writing first, and asking questions later, ask questions first, think “How can this be modelled as a stream of signals” and then write code to cover that model.
This can work on more types of problems in more areas than I can cover in a single blog post. I hope this helps.