Author looks at concepts in Out of the Tar Pit paper, shows that some UI frameworks are actually applying them despite paper having been semi-forgotten, and developed an experimental framework based on those concepts.
There seems to be some confusion here around the R in FRP. I’ve usually seen it expand to Functional Reactive Programming, a formulation which I believe dates back to work by Conal Elliot and Paul Hudak in 1997, and whose influence I believe is explicitly acknowledged by frameworks like, um, React. The OotTP paper is the first I’ve seen to use the term Functional Relational Programming, and of course they cite Elliot and Hudak.
There are lots of possible reasons why the OotTP work wasn’t especially influential. Acronym shadowing might be a minor one.
The “what does FRP mean” problem is even worse than that: Elliot’s FRP idea was about “behaviours”, which are values/functions parameterised by time. To ‘run’ these programs we sample them for different time parameters, e.g. game(0), game(1/60), game(2/60), game(3/60), etc. for the frames of a 60 frame per second game. We can even use different sample rates for different parts, e.g. if a game’s physics engine is expensive we might wrap it in a behaviour which never samples the actual engine faster than 10 times per second, and just linearly interpolates between those at other times.
The problem is, the continuous/parameterised nature of FRP got mostly ignored, so FRP has instead come to mean discrete-time event handling (e.g. Elm, React, …). Elliot’s even distanced himself from the term these days.
PS: One reason continuous-time FRP didn’t originally catch on was it allows past behaviours to be queried, which prevented implementations from ever garbage-collecting old results, just in case they ever got queried at some point. Newer approaches, like FRP Now fix this issue.
I did some searching after OotTP was posted, and came across this among other things (mostly related to miniKanren, Clojure and project-m36). Yet I don’t think I’ve actually seen the FRelP idea manifest in any of these systems.
For example, these slides talk about architectures like Elm, which certainly has the feeder/observer part, but (AFAIK) isn’t particularly relational: it’s state is a big, hierarchical sums-of-products datastructure, with functions operating on sub-trees.
To be honest the feeder/observer part of OotTP was my least favourite: a hack to satisfy the “awkward squad”.
One of the key aspects of relational (logic) programming is that we don’t have “input” and “output” slots like a function: we can provide whatever data/constraints we have, and read off consistent values from any of the others (it might require a slow search, but OotTP tries not to care about efficiency). Applying this “direction agnostic” idea to I/O reminds me of the “propagators” discussed by Sussman. There, a program is like a circuit or network, where the components maintain some invariant on their connectors: specify some values, the others get adjusted to match. Whilst equivalent to the feeder/observer idea in principle, propagators feel more like an interface and less like a black-box oracle. I can imagine two standalone FRelP systems being connected with propagators, performing some best-effort to impedence match. In contrast, connecting systems with feeders/observers make me think of deep, dark rabbit holes of ontological mismatches, semantic gaps, invariant violation, …
FRelP seems to me as a more complex and less powerful abstraction than Functional Reactive Programming. The beauty of FRP is the directed graph approach, which is a simple model that provides a good base for optimization and composition. I found MobX to be a relatively good example of a simplified version of FRP’s principles put to work. I should also point out to the Cells (Lisp) project that is one of the earliest implementation of FRP’s principles (some documentation is available here). I understand why FRelP did not get too popular: the mean reason, to me, is that the relational model constraints on how you model and store your data, while FRP works with pretty much anything.
Going meta: this is a great use of the story description to add context, thank you.
Thank you! Ive tried hard to find ways to use but not abuse it.
There seems to be some confusion here around the R in FRP. I’ve usually seen it expand to Functional Reactive Programming, a formulation which I believe dates back to work by Conal Elliot and Paul Hudak in 1997, and whose influence I believe is explicitly acknowledged by frameworks like, um, React. The OotTP paper is the first I’ve seen to use the term Functional Relational Programming, and of course they cite Elliot and Hudak.
There are lots of possible reasons why the OotTP work wasn’t especially influential. Acronym shadowing might be a minor one.
The “what does FRP mean” problem is even worse than that: Elliot’s FRP idea was about “behaviours”, which are values/functions parameterised by time. To ‘run’ these programs we sample them for different time parameters, e.g.
game(0),game(1/60),game(2/60),game(3/60), etc. for the frames of a 60 frame per second game. We can even use different sample rates for different parts, e.g. if a game’s physics engine is expensive we might wrap it in a behaviour which never samples the actual engine faster than 10 times per second, and just linearly interpolates between those at other times.The problem is, the continuous/parameterised nature of FRP got mostly ignored, so FRP has instead come to mean discrete-time event handling (e.g. Elm, React, …). Elliot’s even distanced himself from the term these days.
PS: One reason continuous-time FRP didn’t originally catch on was it allows past behaviours to be queried, which prevented implementations from ever garbage-collecting old results, just in case they ever got queried at some point. Newer approaches, like FRP Now fix this issue.
I did some searching after OotTP was posted, and came across this among other things (mostly related to miniKanren, Clojure and project-m36). Yet I don’t think I’ve actually seen the FRelP idea manifest in any of these systems.
For example, these slides talk about architectures like Elm, which certainly has the feeder/observer part, but (AFAIK) isn’t particularly relational: it’s state is a big, hierarchical sums-of-products datastructure, with functions operating on sub-trees.
To be honest the feeder/observer part of OotTP was my least favourite: a hack to satisfy the “awkward squad”.
One of the key aspects of relational (logic) programming is that we don’t have “input” and “output” slots like a function: we can provide whatever data/constraints we have, and read off consistent values from any of the others (it might require a slow search, but OotTP tries not to care about efficiency). Applying this “direction agnostic” idea to I/O reminds me of the “propagators” discussed by Sussman. There, a program is like a circuit or network, where the components maintain some invariant on their connectors: specify some values, the others get adjusted to match. Whilst equivalent to the feeder/observer idea in principle, propagators feel more like an interface and less like a black-box oracle. I can imagine two standalone FRelP systems being connected with propagators, performing some best-effort to impedence match. In contrast, connecting systems with feeders/observers make me think of deep, dark rabbit holes of ontological mismatches, semantic gaps, invariant violation, …
I think this is the relevant presentation at LambdaConf: https://www.youtube.com/watch?v=suSuy7l5els
FRelP seems to me as a more complex and less powerful abstraction than Functional Reactive Programming. The beauty of FRP is the directed graph approach, which is a simple model that provides a good base for optimization and composition. I found MobX to be a relatively good example of a simplified version of FRP’s principles put to work. I should also point out to the Cells (Lisp) project that is one of the earliest implementation of FRP’s principles (some documentation is available here). I understand why FRelP did not get too popular: the mean reason, to me, is that the relational model constraints on how you model and store your data, while FRP works with pretty much anything.