Fork me on GitHub
#missionary
<
2024-02-21
>
bbss17:02:05

I'm looking forward to the new docs page on ports. I think I've gotten familiar with the whole api, but am still having trouble wrapping my head around how to integrate missionary into existing applications. I've been having success in using react and missionary together, but am relying on atoms (too much?). I'm also tempted to use mbx a bunch since a lot of the event handlers of third party code often can't be back-pressured. I'm confused on whether to try to wrap this with an ap flow so I can buffer/relieve it, or to just use a mailbox. I feel this reflects some misunderstanding I might be having around ports/flows.

wei18:02:54

if you haven't tried electric clojure yet, it's based on missionary and works well with both atom and missionary style semantics

bbss21:02:14

I have tried electric a while back and should revisit! Would still like to understand missionary well though as I understand that even with electric if you start integrating with third party JS there will be some missionary involved. We make heavy use of a bunch of webgl and js libraries.

leonoel08:02:37

@U09MR0T5Y do you have specific examples where you want to get rid of ports ?

bbss08:02:38

Sure, it's not really that I want to get rid of them as much as I just want to know if I'm having some conceptual mismatch in my thinking wrt when to turn something into a flow vs using a port. For example I'm building graphs using https://reactflow.dev/ and having different types of nodes that connect to eachother. They have an onNodesChange event handler that I thought would be a good place to maintain both the reactflow internal JS model and a clojure model to keep it mirrored/serializable etc. But do I try to wrap the whole thing as a discrete flow, or do I use a flow that consumes events put on it via a mbx/rdv. I hope that makes sense :thinking_face:

leonoel08:02:45

In general, ports are not required unless you want to explicitly describe a cycle. To interop with an event handler, use m/observe and make sure events are consumed quickly, e.g. with m/reduce or m/relieve.

bbss08:02:49

Thank you! Now seem to be the time to start reading up on what exactly a cycle is 🙂. I guess this https://gist.github.com/dustingetz/08c87050df3a26874d41886777422e8e#publishers--observable-sharing-this-is-what-gets-you-from-tree-to-dag-and-is-no-longer-pure-functionalis helpful "going from tree to DAG" and then the ports introduce cycles on top of DAGs?

leonoel08:02:42

Yes, dustin's concept map is valid in both missionary and electric. In my experience use cases for cycles are uncommon, you can go a long way with just DAGs. Cycles are equivalent to feedback loops in control theory

bbss08:02:37

Okay thank you for the references. I guess the proper thing to do is go through the referenced haskell papers. But I'm a bit out of my depth with those and trying to brute-force my understanding as I can really see the value in missionary. Especially in the single-thread main-loop browser where back-pressure is rarely a consideration while it certainly should be.

Dustin Getz14:02:10

> what exactly a cycle is I postulate that cycles are exactly local state. Equivalent to an out of band reference/port (watching, mutating by side effect, and reacting to it). Perhaps there is some advantage to reifying cycles explicitly in Electric or Missionary—for example a visual flow debugger—but neither does so today.

Dustin Getz14:02:04

The root question seems to be: • (a) When should we reach for local state, • and when we do, (b) should we reify the state with a port/reference or with a cycle?

Dustin Getz14:02:25

(b) is a non-question as there are no reified cycles as of yet

Dustin Getz14:02:12

(a) I personally still broadly believe in minimizing state but I am no purist. Electric v2 (the electric-ui4 in particular) has certain problems making necessary the use of local state in kinda hacky ways, that the next iteration we hope will improve upon

Dustin Getz14:02:57

Finally to make clear the equivalence between cycles and state, consider a web application dataflow at large scale: values flow from database -> index -> query -> API -> frontend -> dom -> user interacts -> dom event -> event handler -> backend RPC -> database transaction -> mutate database -> index value is updated -> query should react

Dustin Getz14:02:12

Witness the loop in the above data flow. The database is traditionally modeled as a reference (and transact a mutation of it) but it could also be modeled as a cycle if you had a single holistic graph topology that spanned all platforms including the internals of the database – end to end dataflow through the entire distributed system reified into a single topology

Dustin Getz14:02:17

Electric in principle makes this possible by abstracting over platform seams