[swift-evolution] Dictionary Enhancements

Ben Cohen ben_cohen at apple.com
Mon Feb 20 12:19:34 CST 2017


Thanks Brent.

> On Feb 19, 2017, at 10:37 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
> 
>> On Feb 16, 2017, at 4:26 PM, Ben Cohen via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> 	• init from/merge in a Sequence of Key/Value pairs (already raised as SE-100: https://github.com/apple/swift-evolution/blob/master/proposals/0100-add-sequence-based-init-and-merge-to-dictionary.md).
> 
> Yes, I think this is a great idea.
> 
>> 	• make the Values view collection a MutableCollection (as in this PR: https://github.com/apple/swift-evolution/pull/555).
> 
> Sounds good to me.
> 
>> 	• Add a defaulting subscript get (e.g. counts[key, default: 0] += 1 or grouped(key, default:[]].append(value)).
> 
> I'd really like this to be a broader mechanism—either somehow permitting assignment through `??`:
> 
> 	(counts[key] ?? 0) += 1
> 

My main concern with this (aside from whether it's implementable) is that it isn’t discoverable.

> Or having some kind of `Dictionary` variant with a default value:
> 
> 	var counts = DefaultedDictionary(elements, default: 0)
> 	counts[key] += 1
> 

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.

>> 	• Add a group by-like init to create a Dictionary<K,[V]> from a sequence of V and a closure (V)->K.
> 
> Honestly, this is such a good idea that I might want it to be an extension method in `Sequence` or `Collection`:
> 
> 	extension Sequence {
> 		func grouped<Key: Hashable>(by makeKey: (Element) throws -> Key) rethrows -> [Key: Element] {…}
> 	}
> 
> We don't expose `map` and `filter` as `Array` initializers; why would `grouped(by:)` be one?
> 

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.

>> 	• Add Dictionary.filter to return a Dictionary.
> 
> Sure. If it took a `(Key, Value) -> Bool` predicate, that could even distinguish between the `Array`-returning version and the `Dictionary` one.
> 

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:
let d = [1:"1"]
let f: (Int,String)->Bool = {_,_ in true }
d.filter(f) // [(key: 1, value: "1")]

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.

>> 	• Add Dictionary.mapValues to return a Dictionary (can be more efficiently implemented than composition as the storage layout remains the same).
> 
> Yes, this is something I want.  So do 114 Stack Overflow users: <http://stackoverflow.com/questions/24116271/whats-the-cleanest-way-of-applying-map-to-a-dictionary-in-swift/24219069#24219069>
> 
> 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.
> 
>> 	• Add capacity property and reserveCapacity() method.
> 
> Eh, maybe.
> 

We also have a lack of symmetry the other way too, as there is Dictionary.init(minimumCapacity:), but no RangeReplaceableCollection.init(minimumCapacity:)

>> 	• Have Dictionary.removeAtIndex return the Index of the next entry.
> 
> 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`.
> 
>> 	• (once we have conditional conformance) Make dictionaries with Equatable values Equatable.
> 
> No-brainer—definitely want this one.
> 
>> Please reply here with any comments or questions on the above list, or any additions you believe are important that are missing from it.
> 
> 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.
> 

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.

(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)


> -- 
> Brent Royal-Gordon
> Architechies
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170220/5fcfbb98/attachment.html>


More information about the swift-evolution mailing list