hyperfiddle

2025-02-13T04:30:02.199619Z

So I've done a bunch of reading up on electric clojure and missionary, and I have a few questions. Firstly I see references to differential dataflow, of which I am familiar, but I'm not sure how it's taking place here. If Missionary supports both push and pull semantics, where do the diffs come into play, does each computational unit (process/fiber?) in Missionary carry the full state and allow each viewer to deref it, or get a delta? I'm not sure where the diffs come into play here

leonoel 2025-02-13T09:48:36.587359Z

> does each computational unit (process/fiber?) in Missionary carry the full state and allow each viewer to deref it, or get a delta? Yes. The computational unit is the signal, which is essentially a memoized view of an effect producing a sequence of diffs over time. The process itself is not exposed, its lifecycle is managed (spawned on first sub, killed on last unsub). Subscriptions can occur at any point in time and each subscriber can consume diffs at different rates. Therefore, a reducing function must be provided as argument to m/signal (the diff semigroup) such that successive values can be collapsed (like a squashed commit in git). Each signal keeps track of its full history as a single aggregated diff. A good semigroup function should be able to keep the aggregated diff bounded in memory over an indefinite time (e.g. for sequence diffs, additions and removals cancel each other).

2025-02-13T14:21:04.581929Z

So is the expectation that a remote reader may perform a "read" on the signal every so often and that would reset the diff? From what it sounds like: • push driven parts of the app can push at will and their results will be aggregated into the diff via the reduce function • pull driven parts can get the current value at any time, which would reset the diff. Let's say I wrote a system on this where these signals contain 10k items. With a "snapshot is available at any time" approach it seems like I'd need to have those 10k items in memory all at once. Diffs help, but if a subscriber can arrive at any time, the new subscriber would need a snapshot, hence needing that snapshot in memory at all times.

2025-02-13T14:21:35.454739Z

the dual-driven approach of missionary is interesting though, as is the ability for each consumer to handle updates however they wish

leonoel 2025-02-13T15:37:38.339849Z

that's correct, your dataset must indeed fit in memory

Dustin Getz (Hyperfiddle) 2025-02-13T16:25:53.968179Z

just to be clear, we see a UI as a bounded tree of small collections which is then incrementally written to e.g. the DOM. i.e., all collections are bounded, a fullscreen grid has maybe 100 visible rows

2025-02-13T04:35:20.980049Z

Also if everything is essentially a event stream, how do we make sure events from two sources don't get desynced. Something like timely dataflow combines an idea of a timestamp with the updates, and only advances operators once they all have processed data up to a specific time. It seems like Missionary instead allows each process/fiber/operator to run as far ahead as it has data to process?

2025-02-13T04:37:43.247409Z

I'm finding this all quite interesting, but unfortunately most of the tutorials I've seen are either fairly sparse in details (signals vs streams) or too focused on the user facing APIs (the electric clojure talks) so I'm trying to get a mental model together of the semantics of how Missionary and differential dataflow are processed.

Dustin Getz (Hyperfiddle) 2025-02-13T09:50:32.694499Z

unfortunatelyTim, we are a business, you are not our customer

🍿 2
❄️ 1
2025-02-13T10:50:38.708759Z

I haven’t read it myself so I can’t say for sure it would be helpful, but at least it’s long 🤷 https://nextjournal.com/N-litened/missionary-for-dummies

👍🏻 1
2025-02-13T13:21:07.866409Z

That wasn't intended as a insult @dustingetz, I'm trying to understand the tech in the context of existing work. I'm painfully aware of the issues with Rx, done research into Timely Dataflow, Niad, and the like. At a baseline I'm trying to figure out in what areas hyperfilddle innovates and in which it copies. Based on that I can figure out if I need to dig more into the tech. Every project has its tradeoffs, and I'm trying to find the paradigm that matches closest to the tradeoffs I need to make in my project. The project I'm writing isn't even in clojure, so one of the first things I'm trying to decypher is how much of the magic of hyperfiddle is tied to dom-diffing, the ability to construct a DSL in Clojure, dynamic programming, or any number of other features that I don't have access to. But, I don't want to be a bother, so I'll go poke around in the code more. Thanks for taking the time to answer my questsons thus far.

Dustin Getz (Hyperfiddle) 2025-02-13T13:45:52.845689Z

We are very happy to answer questions, the problem with this particular message at the root of this thread is it does not contain one, rather it contains an expression of your emotions or something. For clarity, a question is a sentence starting with a question word such as "what why how" and ends in a question mark. "Where do the diffs come into play" is an excellent question and therefore it received an answer!

2025-02-13T14:09:23.794639Z

fair enough, let me reframe my questions

Dustin Getz (Hyperfiddle) 2025-02-13T14:14:23.861499Z

excellent, thank you and looking forward!