Should Failed IF Be NULL (and Break My Heart 💔)?

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". :roll_eyes: But it's the first time where I've really seen the choice with true clarity.

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. :frowning:

>> if 1 < 0 [pack ~[]~]
== ~[~[]~]~  ; anti

Such things are legal to construct (they have to be). But I'm wary of them decaying 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 :broken_heart:

  • 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? :frowning:

>> 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. :zany_face: