[swift-evolution] 100% bikeshed topic: DictionaryLiteral

Ben Cohen ben_cohen at apple.com
Tue Jan 9 12:23:53 CST 2018



> On Jan 8, 2018, at 10:12 PM, Chris Lattner <clattner at nondot.org> wrote:
> 
> 
>> On Jan 8, 2018, at 4:29 PM, Ben Cohen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> There exists in the standard library a type `DictionaryLiteral` that deserves naming re-consideration before we declare ABI Stability, because it’s confusingly misnamed, being neither a Dictionary (it doesn’t provide key-based lookup of values) nor a Literal. 
>> 
>> Instead, it’s just an immutable collection of key-value pairs you can create _from_ a literal.
> 
> Wow.  This is really gross, I didn’t know it existed :-)
> 
> Random question for you.  DictionaryLiteral has this doc comment:
> 
> /// You initialize a `DictionaryLiteral` instance using a Swift dictionary
> /// literal. Besides maintaining the order of the original dictionary literal,
> /// `DictionaryLiteral` also allows duplicates keys. For example:
> 
> why is maintaining duplicate keys a feature?
> 

Allowing duplicate keys can be useful depending on the use case.  Though you could argue they shouldn’t be called keys then…

This type can be described as “just an ordered immutable list of pairs that you can declare using the `[:]` syntax because that looks nicer than `[(,)]`” . Allowing duplicate keys, and preserving declaration order, is just what it does.

One thought I had was we could replace it with conditional conformance by making `Array: ExpressibleByDictionaryLiteral where Element = (Key,Value)`. But we can’t do that quite yet, because I think it needs [parameterized extensions](https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions>). Also that might be confusing too ("huh, I can create an array from a dictionary literal???”).

> 
> It also has this one:
> 
> /// Some operations that are efficient on a dictionary are slower when using
> /// `DictionaryLiteral`. In particular, to find the value matching a key, you
> /// must search through every element of the collection. The call to
> /// `index(where:)` in the following example must traverse the whole
> /// collection to find the element that matches the predicate:
> 
> Since it is immutable, why not sort the keys in the initializer, allowing an efficient binary search to look up values?
> 

Because it’s currently in user-declared order, like an array. I don’t think we could change that without breaking any code that uses it for what it does today. Here’s an example in the wild that is reliant on preserving order:
https://github.com/apple/swift/blob/master/benchmark/single-source/RomanNumbers.swift#L28 <https://github.com/apple/swift/blob/master/benchmark/single-source/RomanNumbers.swift#L28>.

We will hopefully add a value-type sorted dictionary too, at some point, which would cover the sorted literal use case.

> 
>> I’m canvassing for opinions on what it ought to be called.  Some suggestions so far:
>> 
>> - `AssociationCollection`: Following the term of art from some other languages. Slightly obscure-sounding to developers not already familiar. Also “association” and “associative” are confusingly similar, which brings back the is-this-a-dictionary problem.
>> - `KeyValueCollection`: Problematic because key-value comes up in a totally different context in Cocoa.
>> - `PairCollection`: “Pair” is kinda nondescript.
>> - Do nothing. It’s not so bad.
>> 
>> The old name can live on indefinitely via a typealias (which has no ABI consequences, so could be retired at a later date once everyone has had plenty of time to address the deprecation warnings). Removing it as not carrying its weight (and instead using `[(Key,Value)]`, which is basically what it’s a wrapper for) is probably off the table for source stability reasons.
> 
> I’m not familiar with this type at all, so I apologize for the dumb question but… why was this added in the first place?  If it is the wrong thing, why not just deprecate it in Swift 5 and remove it in a future release?  

Given it’s going to be in the ABI regardless, and has at least some marginal utility, if we can find a more sensible name for it is there any strong motivation to deprecate it?

> That avoids it being an ABI concern, because we could make it be force inlined into any client code.
> 

"we could make it be force inlined into any client code” isn’t a feature we currently plan on having unfortunately. Also this is a type rather than just a method, so we’d need a feature to always emit the symbol into the client too.

> Finally, is anyone actually using this type?
> 

IMO that isn’t a question we should be asking any more except in cases where an existing implementation is causing active harm. Which, confusing name aside, this type isn’t (aside from API sprawl I guess).

> -Chris
> 
> 
> 

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


More information about the swift-evolution mailing list