Agreed, but in any case, my problem with all the suggestions above is that none of them convey conditionality. You don't just fill, you fill if. The ??= operator in this sense probably comes the closest to what would be the most intuitive way of performing this operation.
But it has the obvious downside: not all Optional.Wrapped == Peg.
To peg an Optional<Bool> sounds weird.
Unfortunate, because I cannot come up with another verb which conveys both:
”The container (Optional) cannot be partially filled” && ”This action does nothing if something already occupies the container”
IIUC, Optional.take() doesn't mean only taking the value but also it means taking the ownership of the value, since it was (re-)introduced as a part of SE-0437 "Noncopyable Standard Library Primitives".
I think the function opposite to take() would be also supposed to take over the ownership of the new value. Copyable value may be passed as well though.
In short, such a function name could be a verb where both "value" and "ownership" can be its object word.
...Although I'm pointing that out, I'm so poor at English that I don't come up with any words for this. accept(_:)? obtain(_:)? receive(_:)? devolve(_:)? give(_:)? offer(_:)? transfer(_:)?
(Phew... they don't imply "if it's nil" at all.)
By the way, whatever the name would be, I may want the function to return the ownership of the passed value if some wrapped value already exists:
extension Optional where Wrapped: ~Copyable {
@discardableResult
public mutating func _nameOppositeToTake_(_ newValue: consuming Wrapped) -> Wrapped? {
switch consume self {
case .some(let alreadyWrapped):
self = .some(alreadyWrapped)
return newValue
case .none:
self = .some(newValue)
return nil
}
}
}
I don't think a ??= operator is worse, but any operators can't achieve such behavior.
Optional.take() was apparently defined before SE-0429 landed. SE-0429’s motivating example is a swap() function that works on a Pair of non-copyable values. We can logically extend this to Optional, in which case assignment is simply discarding the result of swap(): _ = myOptional.swap(newValue).
That said, there have been some other ideas floating around that might render Optional.take() superfluous:
In-place mutation of enum payloads
Referencing enum payloads as storage locations
// Imagining `var` pattern bindings as the syntax for (1):
if case myOptional = .some(var wrapped) {
wrapped = newValue
}
// Imagining a syntax for (2):
myOptional.some.0 = newValue