This thread from November 2020 is a notable historical moment, as it was the genesis of "isotopes".
"Perhaps NULL has an "isotope" that shares its not-able-to-be-put-in-blocks property, but that certain functions treat distinctly. And perhaps it decays, so you can't end up transferring the property into variables besides where the state originates."
It's interesting to note that it originated from a crazy experiment to pipe multi-returns through conditional chains--an unfit idea that is far surpassed by today's ideas. Sometimes you have to try something crazy just to articulate what's wrong with it...and in doing so, you might steer yourself to a novel solution.
Imagine that IF had multiple return values, and one of those values allowed it to indicate if it took a branch:
>> [value branched]: if true [null]
; null
>> value
; null
>> branched
== #[true] ; it could theoretically even return which branch, e.g. `== [null]`
If somehow this piece of "/BRANCHED" (or /SUCCESS, or whatever) could make it through to ELSE, it could be used as the trigger.
For something like this to work, a finished function's frame would stick around long enough to see if a following function needed it...instead of just having the function's output cell. It would not be particularly easy to rig up...but not impossible.
The main design point would be how to know this is what you wanted. Is it just a matter of ELSE taking an argument /BRANCHED, and IF having an output /BRANCHED...so the names line up and it assumes you want them connected?
ELSE could still be willing to run if the /BRANCHED refinement was not provided by the left-hand side, in which case it would be purely NULL-reactive.
I'm not exactly sure what you'd do with:
if true [null] else [2] then [3]
The ELSE would get the first as having /BRANCHED, but then it didn't run...so it's saying /BRANCHED is false. It would mean a THEN after an ELSE would only run if the ELSE ran. So:
>> if true [print "A", 1] else [print "B", 2] then [print "C", 3] ; yay comma!
A
== 1
>> if false [print "A", 1] else [print "B", 2] then [print "C", 3]
B
C
== 3
That's different from today's value-driven (as opposed to branch-taken-driven) logic. It means there's a bit more invisibility to it, but it's explainable...probably more explainable than voidification.
This seems promising enough to try out, despite the likely implementation difficulty. Like I say, it doesn't mean NULL-reactivity can't stick around for ELSE in general...it just would give conditional structures a new way to solve a frustrating problem.