This is one aspect of Bonsai I still do not understand.
| A ->
let%arr change_tab = change_tab in
~attrs:[ Vdom.Attr.on_click (fun _ -> change_tab T.C) ]
[ Vdom.Node.text "jump to c" ]
| B -> Bonsai.const (Vdom.Node.text "why are you even here")
| C -> Bonsai.const (Vdom.Node.text "hello!")))
In particular, my current understanding (no idea if this is correct) is that Bonsai somehow is ‘executing all branches’ and to prevent that, we need something like Bonsai.enum to only bother updating the visible tab.
Is the above intuition correct? If so, if there a write up somewhere of the mechanics of what is going on here (especially with respect to “bonsai executing all branches”) ?
Let’s say we have a dashboard with several pages. Each page is a large and complicated computation, with a lot of data processing and a lot of produced Vdom.
The simple way to display one of the pages at a time would be something like:
let router path =
let%sub page1 = page1 in
let%sub page2 = page2 in
let%sub page3 = page3 in
let%sub not_found = not_found in
let%arr page1 = page1 and page2 = page2 and page3 = page3 and not_found = not_found and path = path in
match path with
| "/" -> page1
| "/2" -> page2
| "/third" -> page3
| _ -> not_found
This component will return the Vdom of one of the pages, as desired. However, it will compute the view for ALL of the pages. Bonsai’s
enum function (and
match%sub) allow you to only compute the path that is shown.
On a side note, Bonsai has a routing library so you don’t need to reinvent that from scratch.
I have a few followup questions.
Does this happen at the
let%sub : 'a Computation.t -> 'a Value.t or the
let%arr : 'a Value.t -> 'a line ?
- So Bonsai.enum is kind of like a ‘match’ right? Is there a Bonsai.### that is like an ‘if’ ? I’m looking for something that does:
bool Value.t -> true_: Vdom.Node.t Value.t -> false: Vdom.Node.t Value.t -> Vdom.Node.t Computation.t (or something like that)
I haven’t worked with the internals enough to answer with 100% confidence. That being said, I’m pretty sure that
let%sub calls “create” a new copy of the incrementally computed
Value.t (and are likely responsible for the cost of computing and caching it), and
let%arr just accesses the precomputed value.
I highly recommend reading https://github.com/janestreet/bonsai/blob/master/docs/blogs/letsub.mdx
If I’m remembering my Bonsai history correctly, there used to be a
Bonsai.if_, which got deprecated in favor of the more general
match%sub. You could just pattern match on true/false.
What were your main take aways from that blog post? Mine were:
Recomputing things is bad.
'a Bonsai.Computation.t as caching / memoization / only computing it once.
let%arr produces Computation.t ; let%map produces Value.t. Value.t recomputes. let%map bad.
Were there any other points to extract ?
- Instead of “recomputing”, I’d say “redundant recomputation”.
- With Bonsai’s current API, I think of
Computation.t as a “blueprint” for an incremental computation, and of
Value.t as the actual incremental computation.
Computation.t multiple times will “create” multiple independent copies from the same blueprint.
Value.t isn’t bad, and
let%arring multiple times from the same
Value.t is the mechanism for sharing work. Iirc, mapping on
Value.t isn’t the issue, mapping on
Computation.t is. But I’m not really sure, and would have to test that.
W.r.t. takeaways, I think that working through the simplified arithmetic DSL helped me understand what
let%arr actually do, and get an idea of what the implementation might be.
This is not a rhetorical question – I genuinely am confused about this. Is it the
let%sub or the creation of the
'a Computation.t that creates the subgraph/node ?
In particular, consider :
let x: 'a Computation.t = ...
let%sub x1 = x in
let%sub x2 = x in
let%sub x3 = x in
Are “independent copies” being created here? If so, of what ?
To expand on this confusion a bit, this notion of “independent copy” and “caching / avoid recomputing” seem conflicting to me in the following way:
If we have an independent copy of something, say a subgraph, it seems, almost by definition, the computation is being dupliicated.