Fabulous with Incremental/Adaptive Views
See original GitHub issueIn “Data Driven UIs Incrementally” (Strangeloop 2018 talk) Yaron Minsky goes through how they built a diff+patch approach on top of functional data structures using incremental to structure the process of updating the model in the Elmish architecture as an incremental computation.
But I still think this falls short of what could potentially be achieved by integrating all of these pieces into a compositional primitive to make it a lot easier to build and extend reactive user interfaces in F#. An abstraction similar to Active Expressions should be possible, although the underlying implementation would be built on an incremental computation model.
If Fabulous was extended to support this kind of architecture maybe it would make sense to decouple that from Xamarin.Forms
? Xamarin.Forms
would still be the canonical implementation, but if someone wanted to plug in say Avalonia instead it would be amenable to it.
Further Reference
Blog Posts
- Self Adjusting DOM
- Self Adjusting DOM and Diffable Data
- Streamlining Incr_dom
- Incremental Computation and the Web
- Designing a Tree Diff Algorithm Using Dynamic Programming and A*
Papers
- Self-Adjusting Computation (thesis)
- Active Expressions - Basic Building Blocks for Reactive Programming
Repos
Issue Analytics
- State:
- Created 5 years ago
- Reactions:14
- Comments:22 (4 by maintainers)
Top GitHub Comments
A quick update: we are working on an incremental/adaptive data library for F#, based on the core of the Aardvark adaptive data implementation, which is tried and tested
https://github.com/fsprojects/FSharp.Data.Adaptive
Early days yet, but I’d like to next experiment next with an adaptive-data version of Fabulous ViewElements. I’ll post here if/when I make progress.
See also https://github.com/krauthaufen/aardvark.web/blob/master/src/Aardvark.UI.Web/DomNode.fs#L13 for an adaptive DOM node type
See also https://github.com/aardworx/aardvark.web/blob/master/src/Aardvark.UI.Web/Ui.fs for the web of reader/updater objects that sit on top of the adaptive data and propagate changes to the DOM
Watching through Minsky’s excellent talk, I notice the following:
First, from about 25min in, I see F# immutable maps should support a “symmetric diff” operation with signature such as
It is necessary to implement this on the core tree of the Map data structure to allow pointer-equality on the internal
Map
structure to be used as a way of detecting “no change” within incrementally derived maps.Next, I wonder if there is scope to experiment with a quotation-based “incrementalization” of Fabulous programs. My thinking is that we put
ReflectedDefinition
on all the MVU code, and thendoes a somewhat sophisticated derivation of an incrementalized version of the MVU program. This would include an incrementalized model type under the hood (not made explicit to the programmer). For example, if the model contains
and the
update
function (unsurprisingly) does incremental updates toValue
for some messages, then the incrementalized program uses a modelin either a Gjallahorn or Self-adjusting computation version of incrementalized or reactive computation. The
update
function would be rewritten to beModel' -> Model'
and the view function would be rewritten to be an incrementalized viewModel' -> dispatch -> Incremental<View'>
. The process of consuming the incremental view would then be ultra-fast, and would not involve re-evaluating the whole view.The
Model'
type would not be explicit to the user and might not actually be generated as a class (it would exist logically in the implementation ofmkIncrementalProgram
but not otherwise).The approach might be extended to allow the use of any data structures in the model that support “diff” and “patch” operations with respect to an underlying incremental-friendly representation, and the ability to correlate those with the actual canonical
update
code.This would be a bit of a research agenda but feels somewhat tractable - it is effectively rediscovering the Xaml/Gjallahorn-style binding structure from the static structure of the code where possible, and would resort to dynamic view re-execution where not possible. An advantage over the OCaml-style code presented by Minsky is that the user would not have to program explicitly using
Incremental
nor Rx-style combinators but can just program in the naive functional programming way. One disadvantage is that the user may not understand which parts of the code are executing incrementally and which are executing using view re-evaluation.