If I were to tell you that I was staring at a gnar...
# present-company
d
If I were to tell you that I was staring at a gnarly set of problems with a major component of the software at work, a component which desperately needs improvement, and thinking... "you know, out of the tarpit is a really great description of the problem I have and the vague solution I have been gravitating towards"... what would you say to me?
I'm re-reading the paper and re-listening to the episode right now to try and glean all the insights and warnings I can. But all the various attempts I've had to imagine the "better version" of this core component end up seeming to have a lot of similarities to "FRP".
k
Which FRP, Functional Reactive or Functional Relational?
d
Both actually! I think the reactive aspect is extremely important to interactive systems. And the data stores I'm considering are relational-ish in nature (e.g. tuple-database) (... well, actually despite being made of tuples it's not really a relational database. But as a primitive it could have a relational layer on top.)
The specific set of influences that are brewing in my mind are: • tuple-database for storing "input state" https://github.com/ccorcos/tuple-database/ • Spreadsheet reactivity for "pure derived state" https://lord.io/spreadsheets/ • Redux/CQRS architecture for accepting updates and propagating them from the source client to a) other connected clients viewing the same object and b) the backend • The CouchDB MVCC model for storing changes offline in "branches" until it can be determined if the current object is in a conflicted state Anyway, this all started to sound somewhat like a franksteined-together version of the tarpit FRP system. 🤔
d
Here's the predecessor paper to the FRP architecture - "AST" http://worrydream.com/refs/Backus-CanProgrammingBeLiberated.pdf
d
Interesting, thanks!
d
And to answer your OP - I think you can't do better! Which is why I'm doing it this way myself. Well, if you squint your eyes and waggle your head it looks pretty similar!
The core common feature of AST and FRP (Relational that is) as far as I'm able to discern, as the two papers are quite dense, is that you have pure functions as your domain logic transforming domain data from state to state.
Since you've separated the state from the functions, the functions don't need to be, and probably shouldn't be, Turing Complete - because they have to terminate.
Here's the tar pit paper for reference: https://curtclifton.net/papers/MoseleyMarks06a.pdf
There's apparently some controversy over whether the FRP model actually entails mutating the relational state that's stored, and if those mutations can be used in subsequent applications of the domain logic. I think it looks like they punted on that a bit.
d
I think that's a matter of taste - you might want to implement an immutable data store that looks like event sourcing, or a mutable relational thing like a standard sql database? But the ideas of expressing domain logic as relational queries is interesting, as is the separation between input state and derived state. I think the struggles of my system really stem from not strictly distinguishing between input and derived state, so everything becomes a big mess. That's why the paper spoke so clearly to my situation.
d
Well an "immutable" data store is still mutable - when you add entries! So it comes back down to storing history or not, which is down to supporting elements of the system that are behind in the sequence of events and not yet caught up with subsequent changes. But after that, you don't need to store history, and if you do, then you must have a domain requirement to do so, in which case, make it explicit with a history table! The question is, how do you get to each new state? AST and my squinty-eyed interpretation of tarpit FRP tell me that you have pure domain functions or derivative relations transforming from state to new or next state. I think Clojure's DB has something like that. As for input vs derived state: well that's an arbitrary distinction, really. I mean, just have derived state as your general model, and then make some state special - inputs - and "derived from something going on elsewhere". Then outputs derive "state elsewhere" from system state. The tarpit called them feeders and observers.