I guess observable enthusiasts around here may fin...
# two-minute-week
m
I guess observable enthusiasts around here may find this one interesting! I'm designing a way for object to "act together" in a more natural way. This involves objects that do stuff (as opposed to simply computing a value) and that can generate their own events. Examples on the video are a Timer (which can be started/stopped and will stop itself automatically after some time) or a KeyPresser (which can be pressed down/released, based on the physical keyboard's keys but may also generate synthetic events, according to notifications received from other objects). On the video you can see a simple Timer-based limiter, that releases the space after half a second. I can press the key myself, and that will cause Automat to start the Timer (you can take a closer look at the hand over the Key Presser - it shows whether the key is pressed or not). And then after some time, Automat will release the key for me. If I release the key sooner, the Timer is cancelled. You can see that the flow of information is multidirectional. The direction is indicated by the movement of belts between gears. That's the first half of the video. One fundamental issue of these observable systems is that the computation would loop forever if the objects just announced their new state on every change. Typically they are only evaluated once, according to some topological sorting (most observable systems don't allow loops) and they also store & compare their state to prevent redundant updates (optional optimization in loop-free reactive systems but absolutely necessary if loops are allowed - it's the stop condition). (terminology: many people call this "feedback loops" and treat this as an undesired behavior, but IMO there are places where feedback loops are a sound solution, so I'll call this "reactive echo" - it's when an object changes state but then notifies the source of the change of its change. Another reason is that "reactive echo" doesn't really need to cause a loop - the issue is that a change notification is accidentally sent back) None of this is new - it's a pretty well known pattern. Fun things start when the OS is involved & objects start to flip-flop fast. This happens when I create a loop with the Timer. This is the second part of the video. The Timer switches itself off & on - but it happens pretty much instantly. This off/on switching still generates notifications for the Key Presser - so it sends the events to the OS. And some time after, the OS sends these events back to Automat. There is a delay caused by the OS. The events differ from the internal state tracked by the Key Presser, so they must be announced to other synchronized objects, causing the Timer to stop & restart instantly. The flow of events is: • I press the key down => "ON" notification sent to the Timer • Timer completes => "OFF" notification sent to the Key Presser, which posts a synthetic "release key" event • Timer restarts => "ON" notification sent to the Key Presser, which posts a synthetic "press key" event • OS sends back the "key released" event to Key Presser => "OFF" notification sent to the Timer (uh oh! it's a reactive echo!) • OS sends back the "key pressed" event to Key Presser => "ON" notification sent to the Timer (again - it's a reactive echo!) The last two events should not be there. But the causal chain of reactive echo escapes the process and arrives back with a delay so it cannot be reasoned about in a local fashion. There is no portable way to distinguish synthetic vs natural events so they cannot be simply ignored. I cannot even attach anything to these events explicitly. They're pretty much indistinguishable from real user events. As you can see on video, it actually works fine - this is because Automat is now using a completely different way to prevent the reactive echo (Automat has five different echo cancellation mechanisms, lol). I like this one the most because it's using a strategy known from biological neurons. You won't find it in the artificial ones! The real biological neurons have an inhibitory period that they enter after firing. This allows them to prevent back-flow of information in a completely distributed fashion - without the need for a central orchestrator that will sequence their activations in topological order - and without the need to track & compare any internal "value" (neurons store no bits - they just "fire" & rest). The way it works in Automat is that whenever a Key Presser sends an event, it records a timestamp - it's the start of its inhibitory period. For the duration of this period it will ignore the next event received from the OS. Very simple solution actually, and widely used in nature - but not so much in engineered reactive systems. But if you think about it - it could be!
❤️ 4
👀 1
i
Great write-up. I might be missing a realization — what makes this "inhibitory" approach different from a "throttle"? ("debounce" is also similar, maybe that's what i mean?)
m
Yes - it's exactly that! A throttle (or some variant of throttle - I'm also not familiar with precise terminology around those concepts). The thing is that this throttle can be used to prevent back-flow of information in reactive graphs. This allows reactive graphs with cycles & multidirectional dataflow - which are otherwise finnicky and prone to oscillations to behave in a more robust fashion.
t
yeah the self-triggering loops are the bane of my existence. @Bosmon claims to have solved bi-direcitonal reactivity in
fluid.cell
https://ponder.org.uk/post/2026-02-20-reactivity-for-malleability/ I am still trying to get my head around it. Your approach is interesting. I feel like there is this modernist approach to coding where we build fragile mathematical towers, a topological sort being a great example of. Then there is the post-modernist approach, where we wire into systems we can't understand (e.g. a user's randomly configured operating system) and then apply techniques to deal with the chaos, which inhibition would be more like. The post-modern can end up more robust and fault tolerant, but ultimately even harder to reason about because its adding more entropy on top of the existing entropy.
👀 1
s
hi, git refernced here. im very much i nteresting in atomation for humans, do you have maybe more demos of this? or a dmeo i can lay wiht?
t
its on steam I think
s
i see cool