You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When I was first trying to figure out Bonsai, I drew a lot of parallels to React paired with the Recoil state management library. Recoil adds an orthogonal computation DAG, rooted in shared elements of state called "atoms", which can be consumed by React components. Changes to atoms propogate down the computation graph and selectively trigger React components to re-render.
If the understanding I've come to have through this discussion is accurate, it seems that in Bonsai, the equivalent to atoms is:
Bonsai.Var, for truly global state, since it acts as a mutable container that can feed into computations via Bonsai.Var.value.
Bonsai.Dynamic_scope, for "semi-global" state which is shared among some computation subgraph.
Is this an idiomatic way of thinking about Bonsai and global state?
As an example of something I'm unsure about, I recently had to build a primitive router/link/url system, where components that depended on the current URL (e.g. fetching a query depending on a path argument) would incrementally recompute as the URL changed. A tl;dr of my implementation:
openBonsai_webopenBonsai.Let_syntaxletget_uri()=letopenJs_of_ocamlinDom_html.window##.location##.href |>Js.to_string |>Uri.of_string
(* This creation of a "global" variable feels like it might be an anti-pattern *)let uri_atom =Bonsai.Var.create (get_uri ())
letset_uriuri=letopenJs_of_ocamlinlet str_uri =Js.string (Uri.to_string uri) inDom_html.window##.history##pushStateJs.null str_uri (Js.Opt.return str_uri);
Bonsai.Var.set uri_atom uri
letcurr_path_novalue()= uri_atom |>Bonsai.Var.get |>Uri.path
let curr_path =Bonsai.Var.value uri_atom |>Value.map ~f:Uri.path_and_query
letlink_vdom?(attrs = [])?(children = Vdom.Node.none)uri=let set_uri =Effect.of_sync_fun (funnew_uri -> set_uri new_uri) inlet link_attrs =
[
Vdom.Attr.href (Uri.to_string uri);
Vdom.Attr.on_click (fune ->
Js_of_ocaml.Dom.preventDefault e;
set_uri uri);
]
inVdom.Node.a ~attr:(Vdom.Attr.many (attrs @ link_attrs)) [ children ]
letrouterroutes=let uri =Bonsai.Var.value uri_atom inlet path =Value.map uri ~f:Uri.path in
routes path
There's a lot to be improved (e.g. functorizing over a fixed variant of routes), but one of the things I noticed is that my approach has a single global Var.t, whereas the "Bonsai web ui url var" implementation provides functions to create separate instances of url vars. Wouldn't the latter approach mean that changes to one url var instance wouldn't propogate to other instances?
The text was updated successfully, but these errors were encountered:
Bonsai.Var, for truly global state, since it acts as a mutable container that can feed into computations via Bonsai.Var.value.
Bonsai.Dynamic_scope, for "semi-global" state which is shared among some computation subgraph.
Is this an idiomatic way of thinking about Bonsai and global state?
Yeah, that's how I think about it at least!
There's a lot to be improved (e.g. functorizing over a fixed variant of routes), but one of the things I noticed is that my approach has a single global Var.t, whereas the "Bonsai web ui url var" implementation provides functions to create separate instances of url vars. Wouldn't the latter approach mean that changes to one url var instance wouldn't propogate to other instances?
Yes, it's undefined behavior to use two Url_var.t. Because of this, we recommend that people make a single instance at the top of their program, and reference it from other components.
When I was first trying to figure out Bonsai, I drew a lot of parallels to React paired with the Recoil state management library. Recoil adds an orthogonal computation DAG, rooted in shared elements of state called "atoms", which can be consumed by React components. Changes to atoms propogate down the computation graph and selectively trigger React components to re-render.
If the understanding I've come to have through this discussion is accurate, it seems that in Bonsai, the equivalent to atoms is:
Bonsai.Var
, for truly global state, since it acts as a mutable container that can feed into computations viaBonsai.Var.value
.Bonsai.Dynamic_scope
, for "semi-global" state which is shared among some computation subgraph.Is this an idiomatic way of thinking about Bonsai and global state?
As an example of something I'm unsure about, I recently had to build a primitive router/link/url system, where components that depended on the current URL (e.g. fetching a query depending on a path argument) would incrementally recompute as the URL changed. A tl;dr of my implementation:
There's a lot to be improved (e.g. functorizing over a fixed variant of routes), but one of the things I noticed is that my approach has a single global
Var.t
, whereas the "Bonsai web ui url var" implementation provides functions to create separate instances of url vars. Wouldn't the latter approach mean that changes to one url var instance wouldn't propogate to other instances?The text was updated successfully, but these errors were encountered: