It would reduce some common if clutter without making the code harder to understand, or conflicting with unary operators.
Examples:
something = optionalThing ?? _
optionaThing != nil ? doSomething() : _
The above seems cleaner than what we currently have to write:
something = optionalThing ?? something
ꜛ This is specially weird, because if you wrote something = something it would be a compile time error! "Assigning a variable to itself", but that is what this expression would resolve to if optionalThing == nil yet it's allowed and it works.
optionaThing != nil ? doSomething() : ()
or:
if let optionalThing = optionalThing {
something = optionalThing
}
or:
if optionalThing != nil {
something = optionalThing!
}
Especially if you have to write many such lines as these.
Letting us be able to say "else do nothing" in the ?: and ?? operators, instead of always specifying a superficial fallback operation, would be no different than not forcing every if to have an else clause, and the _ underscore pattern is already used with for in and other places in the language.
I feel like ?= has the wrong connotation, because putting the ? next to a variable usually means optional chaining, etc. So this implies to me that the left hand side is optional and the assignment is only done if the left hand side is non-nil, which is an opposite meaning entirely. I think =? or similar might make more sense if you want to define a custom operator.
I thought of that, too, after my comment, and after implementing it myself. I don't think that either connotation is obviously-correct for either spelling (?= or =?), and thus is best kept out of the standard library.
Maybe something like
x = _ ?? y
could be allowed for cases where x is an optional var, which would be conditionally replaced with y. However, this would be a new use for _, and is probably not a good idea.
It's not really “else do nothing”, it's “else magically return the value of the variable on the left hand side of the assignment”. This is not very intuitive to me, because if I use y ?? _ in any other context it presumably won't work, making it the only operator with this strange contextual behaviour that doesn't seem to generalise well (i.e. How is this implemented? Can I write my own operators that behave this way? If so, how?). It also doesn't align that well with the use of the _ elsewhere, which is more “don't care” or “discard” than “do nothing”.
??= probably makes the most sense, but it was already proposed and rejected before, so a strong proposal would be required.
My take is that the ternary operators (?: and ??) are not short-hand if statements. They are special functions that return one of two values based on a conditional. This is why they are operators and not statements. I would look at single-argument versions as trying to write x = max(y, _).
The nice thing about Swift is that operators only benefit from being in a standard library if there's a risk that two or more dependancies will each define that operator. As the rational of the previous proposal points out, this operator is rather niche in Swift since it doesn't remove the optionality of a variable, therefore it seems like a good fit to put in one's personal utility library.
I understand now, especially the point about them being special functions.
Allowing an underscore would break things like calling doSomething(with nonNilParameter: Int) with doSomething(with: a ?? _) or doSomething(with: a == b ? x : _) and limiting such usage of an _ in those operators to assignments only would also increase inconsistency.
There is still the possibility of issuing a compile-time error on such usage as the above example, but I suppose then we would be getting into an increasing amount of exceptions to what should be a simple rule.
Having conceded that, I still feel that there should be something done to reduce the boilerplate in common tasks like:
if let optionalThing = optionalThing {
something = optionalThing
}
but custom operators don't seem like the right answer; they would make such common tasks appear a little different in every codebase that uses different custom operators, for one.