Not everyone has historically been a fan of the idea that UNLESS is a synonym for IF-NOT. It’s the same number of characters, and it’s been a source of controversy. When people go around changing if-not to unless, some people change it back because they think it made matters less clear.
I’d come up with what I thought was a more interesting usage of UNLESS, as an infix operator. It would evaluate both the left and the right. If the right evaluated to nothing (NULL) then it would use the value of the left, otherwise the value of the right would override.
>> 1 + 2 unless null == 3 >> 1 + 2 unless <a thing> == <a thing>
I envisioned it being a way of reordering the order you’d read code, where you could put a default first…perhaps wanting it first to emphasize the most common case:
error-id: 0 unless case [ not block? foo  closed? connection  ... ] // don't need an ELSE here, the 0 is up-front
But using it as a defaulting mechanism has the problem that the left-hand side is not in a BLOCK!, so you are always running the default case’s code. Trying to fix this by requiring the left side to be a block would look ugly, and seem a bit of a nasty “surprise”:
thing: [ // looks like a block literal foo baz bar ... x + 100 ] unless [ // oh, wait, that was *code*? :-/ switch z [...] ]
So it seems whatever an infix UNLESS does, it probably always has to run the left-hand side. That means it’s a black sheep if you try to group it in with things like ELSE and DEFAULT.
But what if it was a logical operator, more like OR/XOR?
Imagine if UNLESS was like a version of OR that favored its right hand side, instead of its left. To do this, it would stylize to always have a GROUP! on its right and disallow BLOCK!, because there’s no way it can make a decision without evaluating both sides. (In that way, it would be like XOR…which can’t have a BLOCK! clause on the right)
>> (print "a" <left>) or (print "b" null) a b == <left> >> (print "a" null) or (print "b" <right>) a b == <right> >> (print "a" <left>) or (print "b" <right>) a b == <left>
So UNLESS would just be a tiny bit different:
>> (print "a" <left>) unless (print "b" null) a b == <left> // same as OR >> (print "a" null) unless (print "b" <right>) a b == <right> // same as OR >> (print "a" <left>) unless (print "b" <right>) a b == <right> // DIFFERENT! right result wins out
Psychologically I think the “unless” suggests a test for truthiness of the right. So this is better I think…it had felt forced, to say
foo bar unless if condition [blah blah].
So instead of comparing it with branching constructs like IF/ELSE (where it fell down by evaluating both sides), it’s a logic operator similar to XOR and OR. And still more novel than being a synonym for IF-NOT.
Not picking a definition yet might be the best idea?
Since I just came up with this alternate idea, I can’t tell you how many uses I’d find for it. I’ll have to try looking around consciously looking for use cases. Maybe it doesn’t come up often enough, and people will miss the old UNLESS enough to be worth bringing it back.
I’ll commit the new idea, and we can try it for a while. But the work has already been done to excise UNLESS, and to safely detect old usages and give warnings. There’s a native IF-NOT synonym, and it’s easy enough for people who want the old definition to say
unless: :if-not if they like.
So instead of feeling pressure to decide one way or another, just leaving it undefined in Beta/One and revisiting it a later time might be best.
In any case, I think I can give a definite thumbs down to the idea of putting the left hand side in a BLOCK! to make it more friendly for “defaulting”. So that’s out.