<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="">Thanks Brent.<div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 19, 2017, at 10:37 PM, Brent Royal-Gordon <<a href="mailto:brent@architechies.com" class="">brent@architechies.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="">On Feb 16, 2017, at 4:26 PM, Ben Cohen via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• init from/merge in a Sequence of Key/Value pairs (already raised as SE-100: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0100-add-sequence-based-init-and-merge-to-dictionary.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0100-add-sequence-based-init-and-merge-to-dictionary.md</a>).<br class=""></blockquote><br class="">Yes, I think this is a great idea.<br class=""><br class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• make the Values view collection a MutableCollection (as in this PR: <a href="https://github.com/apple/swift-evolution/pull/555" class="">https://github.com/apple/swift-evolution/pull/555</a>).<br class=""></blockquote><br class="">Sounds good to me.<br class=""><br class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Add a defaulting subscript get (e.g. counts[key, default: 0] += 1 or grouped(key, default:[]].append(value)).<br class=""></blockquote><br class="">I'd really like this to be a broader mechanism—either somehow permitting assignment through `??`:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>(counts[key] ?? 0) += 1<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>My main concern with this (aside from whether it's implementable) is that it isn’t discoverable.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div class="">Or having some kind of `Dictionary` variant with a default value:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var counts = DefaultedDictionary(elements, default: 0)<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>counts[key] += 1<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>I think this is a useful type to have at some point, maybe even this proposal, and complementary to a subscript that takes a default at the point of use.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Add a group by-like init to create a Dictionary<K,[V]> from a sequence of V and a closure (V)->K.<br class=""></blockquote><br class="">Honestly, this is such a good idea that I might want it to be an extension method in `Sequence` or `Collection`:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>extension Sequence {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>func grouped<Key: Hashable>(by makeKey: (Element) throws -> Key) rethrows -> [Key: Element] {…}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><br class="">We don't expose `map` and `filter` as `Array` initializers; why would `grouped(by:)` be one?<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>This is a good point (Nate made it earlier too). I could go either way. In general, we could probably do with a written set of guidelines about exactly when/why something should be an initializer vs a method.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Add Dictionary.filter to return a Dictionary.<br class=""></blockquote><br class="">Sure. If it took a `(Key, Value) -> Bool` predicate, that could even distinguish between the `Array`-returning version and the `Dictionary` one.<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>As it is right now, that wouldn’t distinguish it since Sequence.filter on Dictionary can already take a (Key,Value)->Bool transformation since (Key,Value) is the Element type:</div><div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> d = [1:</span><span style="font-variant-ligatures: no-common-ligatures; color: #b4261a" class="">"1"</span><span style="font-variant-ligatures: no-common-ligatures" class="">]</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> f: (</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">)-></span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">in</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">true</span><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 143, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">d</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">filter</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">f</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">) </span><span style="font-variant-ligatures: no-common-ligatures" class="">// [(key: 1, value: "1")]</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div><div class="">Another suggestion in the opposite direction was that the Filtered type become an associated type on Sequence, which would also allow lazy things to stay lazy generically. This would be source breaking though where current generic code that filters a sequence assumes an array result.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Add Dictionary.mapValues to return a Dictionary (can be more efficiently implemented than composition as the storage layout remains the same).<br class=""></blockquote><br class="">Yes, this is something I want. So do 114 Stack Overflow users: <<a href="http://stackoverflow.com/questions/24116271/whats-the-cleanest-way-of-applying-map-to-a-dictionary-in-swift/24219069#24219069" class="">http://stackoverflow.com/questions/24116271/whats-the-cleanest-way-of-applying-map-to-a-dictionary-in-swift/24219069#24219069</a>><br class=""><br class="">I'd actually prefer that this *not* take a `Key` parameter, because that's more likely to interfere with point-free styles of programming. Reasonable people can disagree on that, though.<br class=""><br class=""></div></div></blockquote><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Add capacity property and reserveCapacity() method.<br class=""></blockquote><br class="">Eh, maybe.<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>We also have a lack of symmetry the other way too, as there is Dictionary.init(minimumCapacity:), but no RangeReplaceableCollection.init(minimumCapacity:)</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Have Dictionary.removeAtIndex return the Index of the next entry.<br class=""></blockquote><br class="">I'm not sure what the point of this is, and I'm not sure if you think this should also be done to equivalent APIs on e.g. `RangeReplaceableCollection`.<br class=""><br class=""><blockquote type="cite" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• (once we have conditional conformance) Make dictionaries with Equatable values Equatable.<br class=""></blockquote><br class="">No-brainer—definitely want this one.<br class=""><br class=""><blockquote type="cite" class="">Please reply here with any comments or questions on the above list, or any additions you believe are important that are missing from it.<br class=""></blockquote><br class="">I'd sort of like to see a protocol for key-value lookup types, sort of like `SetAlgebra` but for dictionaries. I've recently been building a custom dictionary (a `SortedDictionary` type which sorts its elements by key) and not having a protocol to describe dictionaries abstractly is a bit of an irritant.<br class=""><br class=""></div></div></blockquote><div><br class=""></div><div>This probably isn’t necessary at the std lib level until there is more than one std lib type that would conform to it. If DefaultedDictionary or OrderedDictionary were added, certainly.</div><div><br class=""></div><div>(relatedly, SetAlgebra also needs looking at before it gets ABI-locked-down, because while it doesn’t have to be a Collection, it does have a few methods that require you be able to enumerate the elements in the set such as isDisjoint(with:), which precludes things like intentional sets where membership is determined using closures)</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">-- <br class="">Brent Royal-Gordon<br class="">Architechies<br class=""><br class=""></div></div></blockquote></div><br class=""></div></body></html>