Food for thought, @cddr: I am guessing we would want a frozen cell to unfreeze based on further input. If so, we cannot detach from upstream data, the dependencies. Or not all of them, that is, or we will never know when to unfreeze. In which case, the only performance saving will be downstream. But we can already NOT propagate downstream by returning the same value, aka _cache. That would effectively "pause" propagation while preserving all dependency links, and "unpausing" is nothing more than calculating normally.
The use case I was thinking about was the late arriving or out of order events scenario.
I was thinking of a solution that kinda figures out where the late arriving event would go, get the surrounding events from the model that has been built so far, and then replay them (replacing any that changed from the first time around)
Good one. My Algebra app cheats, it provides the client with pulse info which the client then provides with XHR requests so the server can detect ordering gaps and simply await a request that must have gotten delayed. Not an option in this case, unless the individual event sources offer their own sequencing counters. Even then, if there is no guarantee of event delivery, how long do we wait before giving up on skipped data? Clojure time-travel to the rescue? But with a new MX model instance initiated with the "last good" state? ie, We leave the frozen cell and related MX state frozen, mark it as superseded, then, as you say, replay the history for the new MX model. ?? But that ^^^ could percolate up to higher order event processing. ie, Can we just replay the one sequence, or are we in the quantum realm where a new universe (new Matrix) gets spawned at every quantum event? Then we need the whole other MX to freeze and flag it as "superseded". Still thinking-face
Hmm, prolly a problem that in MX we mutate atoms/refs all the time, meaning time travel in the classic Clojure sense is not possible....
Hi π Iβm looking at trying to inspect the DAG within our matrix model. I can see we can use an observer with the c-useds fn to traverse up the graph like
(cF+ [:obs (fn [_ _ _ _ cell]
(prn (tiltontec.cell.base/c-useds cell)))]
effect-fn)
I can repeatedly call c-useds to traverse up the whole tree from a node but Iβm wondering if there is a simpler way to gather the whole dependency tree?Maybe I can quickly knock sth off. Let me gather a rough spec: Do we want the whole Matrix, top to bottom, or up and down from one node? Do we want the moral equivalent of print-depth and print-length to avoid too much output? Is this ASCII-only, console output? We can do sth simple, evolve from there.
The whole matrix would be cool but I think more useful in up and down from a single mode for our use case. For sure console only as this point would be great! Again being able to control the output would be good as well but not that high a priority I donβt think
Ok, I'll pick an interesting formula (feel free to suggest) and do a simple dumper up and down, put cl-format to work.
No, although I often fantasize about creating a DAG viewer from a running app. By "whole dependency tree" do you mean up and down from one node, or simply the entire Matrix? For the latter, we do have tiltontec.model.core/matrix an atom I sometimes populate at app start-up via simply (reset! md/matrix (md/make....)), but it only supports debugging. In fact, there is no _need_ for there to be one matrix, other than fm-navig` which confines its search to one matrix.
ps. c-callers would let you search for cells depending on a cell.
btw, if we are not talking about a UI app, then a "viewer" would involve some clever ASCII art. cl-format to the rescue. But methinks then we would want some way to control how much gets rendered. I started thinking about this a few days ago and realized we would probably want to be able to specify how deep to go, and do separately for callers and useds, and even selectively by c-slot-name, again with depth control etc etc.
btw, why exactly do we want this? I ask this because a global picture of the DAG seems like sth important to have, but I have never aspired to one, so never coded one up. So the details on why this is wanted might change my thinking. Thx! π
Iβm working with @cddr on a back end event processing/enriching pipeline. π It would be super useful for us to be able to visualise when and why cells are updated for explainability of the model + debugging.
Understood. Back in the day I often wondered what was triggering a given formula to run. Before we get to the dag dumper, jus FYI we can inspect tiltontec.cell.base/*causation*, a dynamic var bound to the triggering chain of dependencies. I asked in the other thread about specifics desired, and will knock off a start on this for you to have tmrw.
To be specific, *causation* gets freshly bound just before invoking a Cell formula, so it is a dynamic picture where the dumper will be static.
Ah interesting thanks a lot!
Apropos nothing, Web/MX fans might learn a bit from this response I just made on ClojureVerse to someone looking for a better CSS solution: https://clojureverse.org/t/the-css-problem/9599/35?u=kennytilton
Now they just have to convert their app to Web/MX. π