Skip to content

Instantly share code, notes, and snippets.

@erica
Last active May 11, 2018 22:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/f220dc2b3140bbd388626b28d2d93b9a to your computer and use it in GitHub Desktop.
Save erica/f220dc2b3140bbd388626b28d2d93b9a to your computer and use it in GitHub Desktop.

Renaming the DictionaryLiteral type to KeyValueList

  • Proposal: SE-TBD
  • Author(s): Erica Sadun
  • Status: tbd
  • Review manager: tbd

Introduction

This proposal renames the confusing and misnamed DictionaryLiteral type to KeyValueList. This type is neither a dictionary nor a literal. It is a list of key-value pairs.

There is no strong motivation to deprecate. The type does not produce active harm. Instead, it adds measurable (if small) utility and will be part of the ABI. A sensible renaming mitigates the most problematic issue with the type.

This proposal was discussed in the Swift Forums on the 100% bikeshed topic: DictionaryLiteral thread.

Motivation

This proposal renames the standard library's DictionaryLiteral before the Swift Language declares ABI stability. The type is confusingly misnamed. A DictionaryLiteral is neither a dictionary nor a literal.

  • It offers no key-based value lookup.
  • It does not represent a fixed value in source code.

It seems reasonable to give the type to a better name that fits its role and purpose.

Current Use:

DictionaryLiteral establishes the Mirror API's children:

public init<Subject>(
  _ subject: Subject, 
  children: DictionaryLiteral<String, Any>, 
  displayStyle: Mirror.DisplayStyle? = default, 
  ancestorRepresentation: Mirror.AncestorRepresentation = default
)
  • This implementation depends on DictionaryLiteral's continued existence.
  • The @dynamiccallable proposal will provide another use case for this type.

Even when narrowly used, a type's reach is no longer a sufficient reason to deprecate it or remove it from the language. Absent active harm, source stability takes precedence. In this case, the DictionaryLiteral type causes no measurable harm beyond API sprawl and the issues with its name. The latter is easily fixed.

Current Limits:

The type's doc comments note an inefficient lookup implementation. This issue can be resolved in future Swift releases if needed:

/// 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

Utility:

The type's support of duplicate keys could become be a feature for scanning key-value pairs:

/// You initialize a `DictionaryLiteral` instance using a Swift dictionary
/// literal. Besides maintaining the order of the original dictionary literal,
/// `DictionaryLiteral` also allows duplicates keys.

This key-value pair processing might support custom initializers. It allows duplicate keys and preserves declaration order, which are both reasonably useful features.

Detailed Design

DictionaryLiteral is renamed to KeyValueList. A typealias preserves the old name for compatibility but can be deprecated as of Swift 5.0.

This name was extensively bikeshedded on the Swift Forum thread before proposal. The runner up name was KeyValueArray.

Source compatibility

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 reasons of source stability.

Effect on ABI stability

Should be decided before ABI Stability is declared.

Effect on API resilience

None.

Alternatives and Future Directions

  • This proposal does not change syntax. It processes an ordered immutable list of pairs declared using [:] syntax. This syntax offers better visual aesthetics than [(,)].

  • Swift cannot yet replace DictionaryLiteral with conditional conformance using Array: ExpressibleByDictionaryLiteral where Element = (Key,Value) because parameterized extensions are not yet available. Further, creating an array from a dictionary literal may be unnecessarily confusing.

  • This proposal does not deprecate and remove the type, as Mirror relies on its existence. This proposal does not recommend the removal of the Mirror type as third party custom debugging features rely on this feature.

  • A forum discussion considered a one-time split of the standard library, creating a "SwiftDeprecated" module that could eventually be phased out. That idea lies outside the scope of this proposal and involves a tradeoff between sunsetting APIs in the future for a slight reduction in size of today's standard library. Most applications will not use these APIs, whether such an approach is taken or not.

Acknowledgments

Thanks, Ben Cohen, for pointing out this problem and starting the forum thread to arrive at a better name. Thanks Chris Lattner and Ted Kremenek for design direction. Thanks, Chéyo Jiménez for helping to push this topic.

@lattner
Copy link

lattner commented May 11, 2018

Please don't hinge your proposal on my "gross" comment :-) Your proposal is strong enough sticking to the facts at hand

@erica
Copy link
Author

erica commented May 11, 2018

Updated

@lattner
Copy link

lattner commented May 11, 2018

Feedback:

  • Fix "author(s)" to author: erica

  • "provides children for custom mirrors" -> "is used by the custom mirrors API to provide children" ?

  • "The Mirror initializer depends on this type's continued existence. " -> "The Mirror initializer depends on this type's continued existence, and the @dynamicCallable proposal will provide another use case for this type. "

  • wording could be tightened up: "Although, its implementation is not ideal, as it provides inefficient lookups, this inefficiency can be resolved in future Swift releases if needed:"

  • "A typealias preserves the old name for compatibility." -> I think this typealias be deprecated as of Swift 5.

Otherwise, LGTM, ship it :-)

-Chris

@erica
Copy link
Author

erica commented May 11, 2018

Changes applied. Creating pull request

@airspeedswift
Copy link

Thanks for writing this up. My only comment is that it kinda buries the lede of what it's getting renamed to :) Maybe "Rename DictionaryLiteral to KeyValueArray" as a title would fix that.

@airspeedswift
Copy link

Oh, and I would suggest KeyValueList rather than Array since the array part of the name implies array features it doesn't have. But that could be hashed out on the pitch.

@erica
Copy link
Author

erica commented May 11, 2018

Thanks for writing this up. My only comment is that it kinda buries the lede of what it's getting renamed to :) Maybe "Rename DictionaryLiteral to KeyValueArray" as a title would fix that.

Changing

Oh, and I would suggest KeyValueList rather than Array since the array part of the name implies array features it doesn't have. But that could be hashed out on the pitch.

Changing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment