First and foremost, I think itâs worth noting that the basic building block of Bonsai is 'a Value.t
s and 'a Computation.t
s. The main idea behind composing those is simple:
If I want to use a 'a Computation.t
, I use let%sub
(or another operator), which instantiates a 'a Value.t
. Thereâs a caveat: whatever code Iâm now writing is contractually forced to return a 'b Computation.t
.
Then, I can use let%arr
to define a new 'b Computation.t
in terms of a bunch of Value.t
s.
Thatâs all there really is to composition in Bonsai. For some examples comparing to react, see GitHub - TyOverby/composition-comparison
In Bonsai, not every component needs to be defined in terms of Bonsai.state
or Bonsai.state_machine0
. In fact, most of your components will likely be computations composing other components, or using some other Bonsai utils.
That being said, I wouldnât think of things as Dog.t
, Apple.t
, etc. When you define state components with Bonsai, you get a (Model.t, Action.t -> Effect.t) Computation.t
. in other words, you get the incremental value of the state computation, and also a function you can use to tell the state to change (in adherence to your rigorously defined rules).
So how do we think about composing this? Well, presumably, you care about the value produced by your building block state machines. So youâll use let%sub
and let%arr
to unpack and use those values. Also, since youâre not hardcoding these values, you expect them to change at some point. When might that happen?
- On user interaction, in which youâd use the
inject
function in a virtual Dom effect handler
- On a timer / lifecycle event, in which case youâd also use the
inject
function for a handler
- triggered by other computations processing their own actions. In that case, youâd use the
schedule_event
argument inside that computationâs apply_action
. And of course, youâll need to pass your inject function to that component, either as an input (state_machine1), or as data given to the Action.t.
One of the upsides of Bonsai vs Incr_dom is that you donât need to worry about these .t
s; Bonsai will automatically do that for you behind the scenes on composition.
What you need to think about is what your components produce. If your Widget.t
just packages the cat, dog, apple, orange together so they can be used by other computations, thatâs fine. If it produces something else completely, such as Vdom.Node.t
, thatâs fine too.
Thatâs not necessary at all.
If youâre interested, Iâve finished the first draft of my snake game tutorial. It teaches the creation and composition of state machines. If you have time / interest in test driving it, I would really appreciate any feedback as to structure / format / content: