I gave a mini-talk on this at the San Francisco chapter of Papers We Love back in 2015. These are the notes I wrote down for that, ported over from a previous devlog.
The huge takeaway from this paper can be summed up as:
- ...complexity causes more problems in large programs than anything
- else… it can be tamed—but only through a concerted effort to avoid it where possible, and to separate it where not.
So what is the way out of the tar pit? What is the silver bullet? It may not be FRP1, but we believe there can be no doubt that it is simplicity.
The authors separate programs into three components:
- Essential state
- Essential logic
- Accidental state and control
The essential state is the acknowledgement that some state will be required for the program to be useful. This state should ideally only be the inputs to the system from the user, where the input and user are context-dependent; it could be, for example, data coming from a network connection that’s spun up a new server process. The essential state is the only state that the program explicitly sets out to manage. This means that most of the state present in the program should be derived; it should be possible to recompute given the original inputs (the essential state). The paper also advocates programming in a functional style, where state is explicitly passed as a parameter to a function.
The essential logic is the heart of the program; it is the business logic. To quote the paper, it “comprises both functional and algebraic (relational) parts.” This also contains the logic constraints to ensure the integrity of the program’s state.
The accidental state and control component is “a series of isolated (in the sense that they cannot refer to each other in any way) performance ‘hints’”; the paper notes that these should be “declarative in nature.” For state, the implication is that t his specifies what kinds of accidental state should exist, and how to store it.
Of course, the ideal world is not always congruent with the real world, and so it is that sometimes for performance reasons (or because it is more natural to reason about the problem this way), what would be accidental state in a pure system becomes essential state in the real system.
Also of note is the relationship between these three components:
- essential state is completely self-contained; changes to any other component do not affect the essential state and it cannot refer to any of the other components. However, changes to the essential state may require changes to the other components.
- essential logic is only affected by changes to the essential state, but if changed may require changes to the accidental state and control component.
- accidental state and control is affected by changes to both of the other components, but changes here do not affect either of the other components.