-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative implementation of MutableCollection conformance for OrderedDictionary.Values #262
Comments
Modifying the semantics of (or removing) the The current behavior of Additionally, the (*: Except for wholesale assignments such as That said, we could certainly add a separate view for this purpose, with a different name. Highly relevant prior work is @stephencelis and @mbrandonw's swift-identified-collections package, which implements this view as a top-level type.
This restriction is not implementable in practice. If a collection type implements a subscript setter that does not invalidate indices, then that means that it also inherently supports swapping/sorting/reversing/shuffling/etc. operations. These operations can be (and often are) trivially implemented in terms of subscript assignments. On the other hand, I do strongly wish we had a separate standard protocol that specifically modeled reorderable collections -- ones that can implement MutableCollection → PermutableCollection → Collection Two examples for collection types that would want to be permutable but not fully mutable are, of course, |
@lorentey Thank you for the explanation and background. Unsurprisingly, the choices made for OrderedDictionary.Values are well thought out and are indeed well documented. I now better understand those choices. I must admit that I'm still somewhat hung up on the semantics of "swap" and "sort" for dictionary values and even more so for an "ordered dictionary". If my son told me he was swapping the definitions in a dictionary, perhaps I would think he was switching the definitions for two words with each other. If he told me he was swapping definitions in an indexed list of word/definition pairs, it would be even less clear. If he told me that he was sorting the dictionary definitions, I would never expect all of the definitions to not match the original words. I have no doubt that my definition of "sort" is not the mathematically rigorous definition that Swift intends. However, in a collection that is both ordered and keyed, there remains ambiguity in my mind. I think the functionality that I am envisioning is perhaps more collection and less dictionary. After my initial post, I began working on a KeyableCollection (in progress) which has some overlap with OrderedDictionary and IdentifiedCollection (but uses an underlying array.) It has a dedicated failable replace function. The main consideration in such a collection type is whether to conform to MutableCollection with the heavy cost of needing to throw errors or failing to update if there is a duplication of keys. +1 for PermutableCollection |
We do have the option of adding a new view (or top-level wrapper) that has |
Yes, but... every potential solution that I can think of suffers from the same underlying problem: Enforcing a unique Element.ID is fundamentally incompatible with MutableCollection. For example, IdentifiedArray fails if the Element.ID is mutated, despite the fact that this is not prohibited by the Identifiable protocol. I can not imagine a first-class collection or view, where such failures would be reasonable. Are there other alternative approaches that I am missing? I think I am beginning to prefer a KeyableCollection protocol that does NOT conform to MutableCollection and borrows semantics from the OrderedDictionary library. MutableCollection conformance could be added for Collections where the Element is guaranteed to have a stable ID.
Thinking more broadly, I've been experimenting with other options to address this seeming incompatability between MutableCollection and Element.ID? For example:
Comments welcome. |
Such a view cannot conform to |
@lorentey Ha, well we originally omitted this conformance from So even though We're always open to ideas on how to improve things, though, so feedback is welcome! |
I think the problem here might be in the stdlib & SwiftUI -- if SwiftUI only needs to reorder elements, then it ought to be able to require just that, and no more. MutableCollection requires too much; we might need to consider adding a new protocol. (A new PermutableCollection protocol wouldn't be easy to wedge into the protocol hierarchy at its correct logical position, which does complicate things a bit.) |
As currently implemented (and documented!) when sorting or swapping the OrderedDictionary.Values, the keys do not change positions. For most use cases, I suspect that this is not the desired (or expected) outcome. For example if the key is a unique identifier for a user (a UUID perhaps) and the value is the user's name, sorting based on the name disassociates the user names from their prior identifiers. I am struggling to come up with a situation where this kind of sorting would be desirable.
Potential Fix #1:
Potentional Fix #2:
Additional Thoughts: The current implementation of MutableCollection includes support for sorting and swapping which can lead to unclear behavior in this scenario and others that I have encountered. I wish that Mutable Collection was restricted to using the subscript setter without support for swapping. In an alternate universe, I would have favored a separate protocol perhaps called SwappableCollection that supported swapAt() and sorting. SwiftUI adds to the MutableCollection confusion in that it malfunctions if the included identifier changes or is not unique. It seems to me that we are missing a collection type that would provide first class support in SwiftUI... IdentifiableCollection?.
The text was updated successfully, but these errors were encountered: