[swift-evolution] Proposal: An assignment operator := that ensures nil before assignment.

Brent Royal-Gordon brent at architechies.com
Sat Feb 27 14:33:33 CST 2016

> Here’s a use case. Suppose you are filling out a dictionary in some non-trivial way. However, it should be the case that the value for each key is computed and assigned only once. And so you would use the := operator to ensure this: dictionary[k] := value

This is actually a great use case, and it's exactly the kind of thing you should mention when you suggest a change to Swift.

However, I think that specific use case is better served by a method on Dictionary. Perhaps something equivalent to:

	mutating func initializeValue(value: Value, forKey key: Key) {
		let oldValue = updateValue(value, forKey: key)
		precondition(oldValue == nil, "Initialized \(key) when it was already set")

Why do I think this approach is better?

* `:=` doesn't really explain what it does—if you've never seen the operator before, the most you can be sure of is that it's probably some kind of assignment. `initializeValue(_:forKey:)` *does* explain the intended semantic—this should set a value for the first time—which suggests that it shouldn't be used with a value that's already set.

* I would need to see compelling examples of `:=` used outside of Dictionaries before I thought it would be useful as something applied to any lvalue. Dictionary is an unusual case because they have a dynamically-determined set of keys which are created simply by assigning them, so it's reasonable to not know whether a particular key is `nil` or not. Swift variables and properties, and most Swift collections, separate adding a value from updating it, so they may not need an analogous operation.

* By putting the precondition inside `initializeValue(_:forKey:)` itself, the error message can actually include the key, which may aid in debugging.

Brent Royal-Gordon

More information about the swift-evolution mailing list