I think this consideration is putting too much emphasis on the return value.
We tend to use participle verb forms for non-mutating methods; think of String.append(_:) vs. String.appending(_:). In this case, there's no such pairing, but the mutation of the Optional itself suggests to me we should stick to the imperative like put or bind and let the warning on an unused return value handle the rest.
With that in mind, I think both put and bind read fairly well; put is maybe a bit more explicit about the consuption of its argument, whereas bind makes the return value a little more understandable at the call site:
var itemsRef = cache.opt.put(items)
// or
var itemsRef = cache.opt.bind(items)
Bindings have come up recently in the context of borrowing let vs. Ref: how the first is a binding while the latter is a value, and why it might be useful to have both expressions of the same underlying concept. In this framework, “binding” is a strictly compile-time operation; its program-visible analogue is “assignment”. (A program can get involved in assignment by implementing subscripts and property getters and setters; it can’t alter or observe a binding of a variable to an expression.) It would be unfortunate to muddy that distinction by calling this operation bind. (Alternative suggestion: assign.)
As far as gerund versus infinitive, I don’t think the return result is nearly as important as the replacement semantic, and I could even see an argument that this operation should be @discardableResult. So put over putting.
I'm not sure I follow this. Isn't this, where we discard the result of put:
var x: Optional<SomeNoncopyableType>
let y: SomeNoncopyableType = ...
x.put(y)
just the same as either of these?
x = consume y
x = .some(y)
With @discardableResult, we'd be introducing a third way to write that basic assignment. The result is the whole point of the put operation, or you'd use one of the other two forms.
Controversial take: The name of this operation is "elegantly" (by some definition of the word) solved in C++ because T::operator= returns a T&. I suppose doing that is a bridge too far for Swift. A change like that would be source-breaking anyway, since I'm sure a lot of code relies on x = y having a Void type for the sake of closure return type inference, etc.
I find the symmetry with take to be a compelling argument for put.
Given that the method is on a pure wrapper type like Optional, I think the name doesn't need to suggest a return value. Regular assignment remains available for code that doesn't want a MutableRef back. There isn't any other return value that would make sense to return from the method, so suggesting in the name what gets returned is a non-issue in my view.
Importantly, the ref method wouldn't necessarily be replicable with the mutableRef method. With mutableRef, the optional would be mutated for the entire lifetime of the returned reference, because the returned reference could write to the optional. With ref, the optional would only be mutated while ref is executing, because the returned reference can only read, not write, the optional.
var value = Optional(0)
// `value` is mutated here.
var ref = value.ref(fromAssigning: 1)
// `value` is now just borrowed, so it can be printed.
// If `ref` were a `MutableRef`, it would still be
// mutating `value`, so this would be impossible.
print(value)
print(ref)
Rust doesn't have an equivalent to the ref method because this kind of lifetime dependency isn't expressible, where a value is mutated for a smaller lifetime than it is immutably borrowed.[1] (It would be possible if mutable references could have two lifetimes, one lifetime for when the value is being mutated, and another lifetime for when the value is being immutably borrowed. Analogously, in Swift, the ref method would be replicable with the mutableRef method if the MutableRef type had two lifetimes instead of one.)