Antiforms are weird, and creating them (or tolerating them) when you didn't mean to is good to avoid.
Unstable antiforms are particularly weird...for instance antiform BLOCK! cannot be stored in variables. In normal assignments it decays to its first element, while multi-assignments and other particular constructs interpret it as multiple values:
This is how multi-return functions are implemented.
What's nice about UNQUOTE vs UNLIFT is that if you are really not suspecting you're dealing with a quasiform that should become an antiform, you can avoid the potential confusion caused.
And QUOTE has a similar convenience of not tolerating an antiform when you didn't think there'd be one.
A narrower operator of QUASI and UNQUASI exists to make it clear when you're only adding or removing a quasi state. So you can QUASI only plain non-quoted things, and UNQUASI only non-quoted quasiforms. Then NOQUASI will pass through all values except drop the quasi from quasiforms.
Just helps readers get their bearings on what's going on if that's all that's happening.
COMPOSE has a great feature of being able to add quotes to the slot, by grafting the quotes that are on the slot onto the synthesized result. It adds onto existing quotes:
I've struggled with the question of whether or not to be willing to do this, instead of erroring.
If it were to be done, it would certainly have to only do it to antiforms after they decayed. We don't want it to be composing in quasi-errors instead of reporting them. PACK!s shouldn't be composing as packs, but as the decayed values.
But how bad is it if we are willing to quasify stable, decayed, antiforms?
I KNOW this would be very useful.
We'd still be getting errors on trying to compose in NULLs to slots on regular compose, and it's only when you used this feature that it would be suppressed.
Having it be a refinement, like compose:relax... e.g. relax in the sense that you don't error on nulls when you don't absolutely have to, feels awkward.
I Think I Like Reverse-Biasing The Safety
I guess the way I'd put it is: if you think the safety is important, don't put the quotes on the outside of the group. Put it inside:
>> compose [field1: (quote first [a]) field2: (quote expression-maybe-null)]
** Error: that expression turned out to be null
Quotes on the outside then becomes a power-user feature, and it does what a power user wants:
Yup. I think I like that. Put your quoting inside if you want the null protection, makes sense.
What About Composing VOID In Quoted Slots?
VOID is a PACK!, but it's an undecayable one, so it has special handling nearly everywhere.
Actually this clears up a loose end:
>> compose [''(void)]
== ['~[]~]
Today you get a sort of outlier error there, telling you that void can't vaporize, because [''] isn't legal. I like the idea that there's a behavior/answer.