<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Just to clarify: It seems like the&nbsp;<i class="">only</i>&nbsp;ABI-affecting change here is the type of keys/values. As you note at the end of your proposal, this should just be Dictionary.Keys/Dictionary.Values regardless of whether we implement this proposal or not, in which case this can be punted for Swift 4. It should be fine to keep .Keys/.Values resilient so that we can change their implementation details later if we want.</div><div class=""><br class=""></div><div class="">On the actual proposal: this is a pretty reasonable given Swift’s current design and constraints. That said, I expect pushing forward on this kind of thing right now is premature given the goals of Swift 4. A major aspect of Swift 4 is reworking the way CoW semantics function internally, which could drastically affect the way we approach this problem.</div><div class=""><br class=""></div><div class="">I’d really like if we could eliminate the “double search/hash” in the no-existing-key case. There are ways to do this really cleanly, but they probably involve more advanced CoW-safety propagation. In particular, you want some way for the collection to return its search state to the caller so that they can hand it back to insertion to just resume from there.</div><div class=""><br class=""></div><div class="">For instance:</div><div class=""><br class=""></div><div class=""><font face="Courier" class="">map.entries[key] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // An enum like Found(Value) | NotFound(SearchState)</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp;.withDefault(value: []) // Unwrap the enum by completing the NotFound(SearchState)</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp;.append(1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Now we have a value in both cases, we can append!</font></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Or more complex:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier" class="">map.entries[key]&nbsp;</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp;.withDefault { /* logic that computes value */ }</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp;.append(1)</font></div></div><div class=""><br class=""></div><div class="">I think this can be made to work in the current system if withDefault is actually `[withDefault:]`, which is fine but a bit weird from a user’s perspective.</div><div class=""><br class=""></div><div class="">In an ideal world the user could actually pattern match on the result of `entries[key]`. In this way they could match on it and perform special logic in both cases for really complex situations. This would make withDefault “just a convenience”, so we aren’t pressured to add more methods like it every time someone has a new Even More Complex use-case. e.g.:</div><div class=""><br class=""></div><div class=""><font face="Courier" class="">switch map.entries[key] {</font></div><div class=""><font face="Courier" class="">case .Found(entry):</font></div><div class=""><font face="Courier" class="">&nbsp; if entry.value == 10 {&nbsp;</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; entry.remove()</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; print(“Found a value too many times! Moving key to fast-path auxiliary structure…”)</font><span style="font-family: Courier;" class="">&nbsp;</span></div><div class=""><font face="Courier" class="">&nbsp; } else {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; entry.value += 1</font></div><div class=""><font face="Courier" class="">&nbsp; }</font></div><div class=""><font face="Courier" class="">case .NotFound(entry):</font></div><div class=""><font face="Courier" class="">&nbsp; entry.insert(1)</font></div><div class=""><font face="Courier" class="">&nbsp;&nbsp;print(“Found a value for the first time! Registering a bunch of extra stuff…”)&nbsp;</font></div><div class=""><font face="Courier" class="">}</font></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">But again, this is all dependent on a much more powerful SIL/ARC, and we just don’t know what we’re going to get at this stage.</div></body></html>