Something Big (May) Affect This Question
The stable antiform state currently known as "~void~" is losing the name "VOID" to the unstable antiform state that has been called "NIHIL" (of late).
Should VOID Assigns Mean "Fully Remove A Key"?
It's not the first time empty antiform block will have been called "void". But it's the first time where I've really seen the choice with true clarity: void has to take the name of a nothingness state that cannot be stored in a variable at all.
Okay then... but...
What should we call a state that a variable CAN hold which indicates "vanishing intent" when passed to something like APPEND or COMPOSE? (...and this state also indicates wanting to "opt out" of an operation like INDEX OF, so it gives NULL back...)
"I Have A Question..." 
"...why do you need a stable antiform state to represent vanishing intent? Why can't this just be done with the unstable antiform?"
>> append [a b c] ~[]~
== [a b c]
>> index of ~[]~
== ~null~ ; anti
Then we'd just say that OPTIONAL produces the unstable antiform:
>> optional null
== ~[]~ ; anti (e.g. "new void", no longer called "nihil")
What sucks about this is that suddenly, any function that wants to speak about opting out in this way has to take a ^META parameter. I've resisted designs that force meta-parameterization onto everything everywhere, that was not the intent... only exceptional cases should require it.
Could A Stable State Be A Proxy For Unstable Intent?
Maaaaybe? (no pun intended)
Like, if you marked a parameter in a certain way it would receive VOID as something like an empty splice. Often, an empty splice is a pretty good stand-in for a void.
>> spread []
== ~()~ ; anti
>> append [a b c] spread []
== [a b c]
So what if APPEND could say "if the argument is an ~[]~
antiform, receive it as an ~()~
antiform instead"?
>> opt third [d e]
== ~[]~ ; anti
>> append [a b c] opt third [d e] ; receives ~()~ and not ~[]~
== [a b c]
Maybe it's as simple as saying: if a non-meta parameter typechecks for empty splices, that's what voids turn into.
Okay, no... can't be that simple. If it were, then IF would typecheck splices as truthy, and hence voids as truthy. Needs to be an annotation of some kind. Or maybe you explicitly have to say ~()~
in the typecheck, vs just ANY-VALUE?.
I Propose Catchy Name For Empty Splice: HOLE
In the naming game of musical chairs
, HOLE hasn't found a seat yet...
It seems pretty good to me...
>> hole
== ~()~ ; anti
Though @BlackATTR says it's like the goatse emoji... maybe the name doesn't help. But I guess we'll just have to accept that. There's only so many shapes and so many words, everything will be corrupted or turned to slang anyway, BLOCK! will be a term for genitals soon enough (if it's not already, look what they did to "unit"). Anyway enjoy what non-censored words you have while you can... I guarantee the long tail of the moronosphere means w3'll 44l h&v⬠2
lyk th*s soon enough.
I digress. Back to the central question...
Do I Still Want IF Returning VOID If It's Unstable?
So, what are the implications of this?
>> if 1 > 0 [<hmmm>]
== ~[]~ ; anti
There's one bad impliciation... and it's pretty bad indeed, I'm afraid. If ELSE is to work in this case, we have to make it so that empty packs themselves get packed:
if 1 < 0 [pack []] else [print "Don't want this to print..."]
The branch can't return an empty antiform pack if that triggers else. It has to return a pack inside a pack, e.g. unstable antiform ensconced in an unstable antiform.
>> if 1 < 0 [pack ~[]~]
== ~[~[]~]~ ; anti
Such things are legal to construct (they have to be). But I don't think they should decay automatically. And having them arising in such simple circumstances is a deal breaker:
>> if 1 < 0 [if 1 > 0 [<ack>]]
** Error: Cannot automatically decay ~[~[]~]~ ; antiform
The alternative would be that we get voids as a THEN-trigger (so only null doesn't trigger THEN, and triggers ELSE) or that they are errors. I don't think they should be errors, because I believe loops that don't run their body ever should return void... and I want you to be able to write:
while [...] [
...
] else [
; whatever you want done if there's a BREAK
]
In the past the handling for a loop that never ran its body was that it would run the ELSE. But I feel now that shouldn't be the case--ELSE should exclusively mean it encountered a break.
So It's Settled, My Heart Has To Be Broken 
-
Unstable antiform VOID triggers THEN, and not ELSE... like all other PACK!.. emptiness makes no difference.
-
IF returns NULL, like every other branching construct.
What Makes Voids If Not IF?
While I proposed IFF
I now realize that is a really bad idea. It's way too easy to just see an IFF and go tack on an ELSE clause without thinking "hey, I can't use ELSE with that".
So it would have to be a completely different word. I like WHEN
>> compose [a (when 1 > 0 ['b]) c]
== [a c]
A design idea I had here was that this would be distinct from ? IF, because if you put the OPT on the outside of the construct, then you turn any null into a void... even if it originates from the branch.
>> ? if 1 > 0 [<foo>]
== ~[]~ ; anti
>> ? if 1 < 0 [null]
== ~[]~ ; anti
But I thought WHEN would be used when you expect the branch to produce a value... and catch cases when it didn't, by letting it produce NULL. It wouldn't have to box the null... which means you could use WHEN with ELSE, but it would only run the else clause if the branch was taken and produced null...
Is there another word that would convey this property?
>> xxx 1 > 0 [print "ran branch null] else [print "ran else"]
>> xxx 1 > 0 [print "ran branch null] then [print "ran then"]
ran then
>> xxx 1 < 0 [print "ran branch" okay] else [print "ran else"]
ran branch
>> xxx 1 < 0 [print "ran branch" null] else [print "ran else"]
ran branch
ran else
That's a pretty weird set of properties to exploit... weird enough that it would be nice if you could actively prevent using it with THEN or ELSE. But there's only one way to do that, which is to return antiform comma (a "ghost") and act like a comment. This would work in the specific case of COMPOSE if it was the only thing in the slot, but not if there were any code--even a PRINT statement--before it.
I guess the word WHEN doesn't go with THEN or ELSE verbally (when ... then) or (when ... else) so maybe that's enough of a clue you shouldn't do it unless you are a weirdo and think you know what you're doing.