Multiple values are the achilles heel of the observable workflow. The problem is this:
Here, A triggers B and C, and both trigger D. In order to avoid a double update of D, A should first do B.val = new_value
, then C[] = new_value
.
βββββββ
βββ€ A βββ
β βββββββ β
β β
β β
ββββΌβββ ββββΌβββ
β B β β C β
ββββ¬βββ ββββ¬βββ
β β
β β
β βββββββ β
ββΊβ D βββ
βββββββ
Now B has another listener, E. We canβt do B.val = ...
anymore because E
wonβt be updated. But we can still do C.val = ...
and B[] = ...
.
βββββββ
βββ€ A βββ
β βββββββ β
β β
β β
ββββΌβββ ββββΌβββ
βββ€ B β β C β
β ββββ¬βββ ββββ¬βββ
β β β
β β β
ββββΌβββ β βββββββ β
β E β ββΊβ D βββ
βββββββ βββββββ
But if C
also has a second listener, F
this is impossible:
βββββββ
βββ€ A βββ
β βββββββ β
β β
β β
ββββΌβββ ββββΌβββ
βββ€ B β β C βββ
β ββββ¬βββ ββββ¬βββ β
β β β β
β β β β
ββββΌβββ β βββββββ β ββββΌβββ
β E β ββΊβ D βββ β F β
βββββββ βββββββ βββββββ
You cannot avoid updating both B
and C
if you want to trigger their listeners E
and F
, which means D
is updated twice. But if B
and C
store arrays whose lengths change with the update of A
, it can be that the first update of D
, after B
is triggered, errors because B
and C
have different lengths in that moment. In that case itβs impossible to update all observables correctly. Weβre still trying to figure out ways in which we can make the updating process simpler, but itβs a thorny issue and observables are deeply ingrained in the whole codebase, so we must be careful not to break anything with a βfixβ.
I say this because you asked what to do with a tuple resulting from lift
. But this usually happens because one calculates multiple input arguments for an inner plot object from input observables. In that case, one has to define all the observables beforehand, and carefully update them inside an on
or onany
function with obs.val = ...
and only once (if possible) with obs[] = ...
so that one doesnβt trigger duplicate updates downstream. But as I showed, this is sometimes impossible. Hereβs one example of such a thing: Makie.jl/contourf.jl at master Β· MakieOrg/Makie.jl Β· GitHub
The colors
observable is not triggered, its content array is just mutated. This way the downstream poly
will have access to the new colors when its input observable polys
is triggered. This way polys
and colors
can always have the same length from the perspective of the poly
plot. But this wouldnβt work if something internal to poly
relied on the color
observable actually triggeringβ¦