SE-0214 - Renaming the DictionaryLiteral type to KeyValueList


I followed the original thread and think that the confusion there is evidence that this needs to be updated

This is a good point. Initially I also suggested List because I thought something like Collection would be long.

I think it would be really nice to have some naming convention for non mutable collections (as in copy on write vs in place mutation).

I support the name change.

I think KeyValueList is an appropriate name and would remove much confusion. Reading KeyValuePairs, I imagine the contents of a collection, rather than a container: A KeyValueList contains KeyValuePairs. I'm probably way off there :grinning:

A rename is a very good idea. I prefer KeyValueArray because it describes the type’s performance characteristics more specifically, but KeyValueList is fine too.

By the way, I’ve used this type recently and it’s very handy. I’m glad that it exists.

1 Like

Given that you used the type, how could you suggest it be improved preferably without many API changes beyond say, enhancing subscripting? Improved for performance? Improved for conformance?

  • What is your evaluation of the proposal?

Soft +1. Don't really like either the present name because it isn't a dictionary or a literal and don't really like the proposed name because List has no precedent in Swift and carries baggage from other languages - prefer KeyValueArray.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Marginal, its not like it is a commonly used type.

  • Does this proposal fit well with the feel and direction of Swift?


  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?


  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Followed evolution discussion. Have never used the type myself.

It was perfectly fine for what I needed from it (which was pretty much to just list name-value pairs, but preserve their order so I could iterate over them in that order). If you wanted me to suggest a change, I'd say add MutableCollection and RangeReplaceableCollection conformances to make the type more useful—if it's not just a "literal" anymore, there's no reason to keep you from modifying it.


I realize that this is coming in late, but let me add some context. The only purpose this type was designed to serve was to be used as the parameter type of a method or init that accepts a dictionary literal as an actual argument, when you don't want to lose the specified syntactic order, hash the keys, allocate new storage, or even necessarily have hashable keys. In other words, it is used for its syntactic qualities. Since "dictionary literal" is the name of the syntactic element this type supports, use sites of this type name read well.

Actually, @gribozavr gave a much more complete explanation of all this in the original thread and I think if people were still confused after that, instead of reading his post they probably read the documentation for the type, which as he points out does not at all explain the type's purpose.

I can see that if you wanted to store one of these things or create it and then pass it to a method later, it might make sense to call it something else. KeyValueBuffer would not be terrible. It is like an UnsafeBufferPointer without the Unsafe part, and—since it doesn't expose reference semantics—without the Pointer part.

Correction: 2016-05-28 the following statement is wrong; it holds an array and could easily be made mutable and extended.

I wrote:

That is not possible without compromising performance. Right now it simply refers to the memory the compiler created for us and doesn't do any storage management, COW, etc.


Buffer seems like a very active term for such a static thing. What is it “buffering”?

I think I get the similarity with UnsafeBuffer in a sense. But UnsafeBuffer’s buffer-ness makes sense, to me at least, because it’s a way of taking a pointer to a buffer and making that pointer into a collection-conforming Buffer type. It doesn’t seem to follow that other things that are similar to it in other ways should be named similarly.

I see your point, which rather goes to mine: this type is not much more than a vehicle for communicating a dictionary literal, and all the other names begin to imply that it is something else.

1 Like

dynamic callable’s usecase. One of the reasons why I liked something along the lines of ParameterList. I agree that KeyValue makes it seem like a dictionary but I think it’s something we can live with.

I could be mistaken but AFAICT DictionaryLiteral is currently a poor fit for the use case in that proposal (I haven't been able to find the code that shows how it's used). Before anybody goes renaming this type, someone should demonstrate at least one or two working implementations that use it to good effect and where another name would be an improvement.

Given context from @dabrahams, DictionaryLiteral seems like a reasonable name and it matches ArrayLiteral etc. Perhaps some better documentation would help though.

There isn't an ArrayLiteral type, though. The ExpressibleByArrayLiteral initialiser requirement is

init(arrayLiteral elements: Self.ArrayLiteralElement...)

Hi Dave,

I understand your historical note, but I respectfully disagree that we should keep the existing name. To be clear, this is my personal opinion, I'm not speaking as review manager. Here's my rationale:

  1. From the thread, there is ample evidence that the name of this type is actively misleading and confusing.

  2. Types like this are nouns, which describe their value, not their purpose like you are arguing for. A better name along the lines that you're arguing for would be something like DictionaryLiteralInitializerValue or DictionaryLiteralArgumentValue because that is what you're arguing the value of this thing is supposed to be used for.

  3. We don't (generally) name types based on what they are "supposed to be used for", we name them based on their capabilities and expect/hope that they will be used in new ways. I agree that one important use is to represent dictionary literal values in arguments. However, it is also very useful representing keyword arguments in the upcoming @dynamicCallable proposal, so the historic name is already losing value.

I agree with you that a key aspect of this type is that it isn't mutable. Another key aspect is that it can represent redundant keys. Another is that it (because of its expressible by dictionary literal conformance) it represents key/value pairs. As such, I think that a name along the line of KeyValuePairs is the best direction to go here - as was proposed upthread.



I am happy with KeyValuePairs if that's what the team decides on. It is an accurate name that does not promise utility or performance the type does not support (as could be the case with, say, Array), does not overlap with potential types (apparently a concern with List), nor cut off avenues of extension for more capabilities (as might be the case if its APIs conflicted with the name, such as adding key-lookup and returning an array of matching values if the name of the type contradicted key-lookup-support).


It's abundantly clear that there's confusion, but—to me at least—it's not at all clear that the name is the source of the confusion.

That argument doesn't hold together for me at all. I don't know what other types you'd describe as being "like this", but the prominent types whose names are nouns don't work the way you say. Does the name "Array" describe the value of its instances somehow? No, as you note below it describes their structure, capabilities, and performance characteristics, all of which point to what it should—and should not—be used for. Likewise "Int".

Great, show me some code. Are you saying that you're not using DictionaryLiteral simply to transport the value of a dictionary literal expression from one place to another? As far as I can tell from where I stand, that's currently the type's only capability. It is not clear why

typealias KeyValuePairs<K, V> = DictionaryLiteral<K, V>

is not what you need to make your code more expressive, or why, if you're not actually interested in the “dictionary literal” aspect of the type, you wouldn't be using

typealias KeyValuePairs<K,V> = [(key: K,value: V)]

It's not at all that I'm attached to the existing name—KeyValuePairs isn't terrible, but it does seem to imply it will do much more than it actually can today. This proposal seems to be introducing source churn and general work without addressing what looks to me like the source of the confusion—the documentation—by renaming a relatively unimportant type, without demonstrating how a name change improves real code.

Sure. The implementation of @dynamicCallable will be posted soon. It "transports" the contents of a keyword argument list (which is exactly identical in structure, but different in syntax from dictionary literals). This is one pertinent example why it isn't always a great idea to name a type after its first client.



This statement again makes me wonder why [(argumentLabel: String, value: Any)] doesn't serve your purpose far better than DictionaryLiteral currently does. AFAICT you're totally hitting this nail with a suboptimal choice of hammer.

I'd say if there's a lesson here, it's likely to be that it's not a great idea to put something in the standard library when it's only got only one real client.

The proposal is not opinionated about choice of type to implement this with, I just expect DictionaryLiteral to be a common choice. The Python glue uses it, because the actual design of the type is a good match for its needs. A Dictionary would be less efficient.

Completely agreed. In my opinion, this type should never have been public. I argued for removing it on the grounds that we would never add it now if it were not already in the stdlib, but others disagreed - yourself included IRC.

Given that it is a public part of the standard library and unlikely to be removed, I would really like to rename it to something that isn't so confusing.