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β¦