pointfreeco / swift-identified-collections

A library of data structures for working with collections of identifiable elements in an ergonomic, performant way.
MIT License
539 stars 46 forks source link

Sendable, Mutable/RangeReplaceableCollection Conformances #41

Closed stephencelis closed 2 years ago

stephencelis commented 2 years ago

This PR adds a few conformances we discussed.

First, it adds a conditional Sendable conformance, which should be non-controversial. Swift Collections already adopts these conformances upstream, though we must remain @unchecked given that we hold onto a key path under the hood. If we ever require Identifiable in the future, then we could relax this @unchecked constraint when an update to Swift Collections is released (though its conformances are @unchecked as is).

Second, it upgrades its "partial" MutableCollection and RangeReplaceableCollection conformances to actual conformances. This is maybe more controversial. While we have been conservative and preserved the conformance capacity of the underlying OrderedDictionary, we believe that we can and should relax this restriction. First, IdentifiedArray should be thought of as an array of identifiable items, first and foremost, and not as an "ordered set" or "ordered dictionary," despite our preconditions that an item may only appear once per collection and never modify its identity, and despite our use of OrderedDictionary under the hood for storage.

Adding these conformances should enhance how IdentifiedArray is used in SwiftUI. For one, MutableCollection will allow us to pass a binding of an identified array to a ForEach view:

ForEach($model.identifiedPeople) { $identifiedPerson in
  TextField("Name", text: $identifiedPerson.name)
  Toggle("Administrator?", isOn: $identifiedPerson.isAdmin)
}

And RangeReplaceableCollection will allow us to pass a binding of an identified array to a NavigationStack:

NavigationStack(path: $model.identifiedDestinations) {
  // ...
}

Can anyone think of any issues with supporting these conformances? Are there guarantees that MutableCollection and RangeReplaceableCollection provide that we are skirting, and even if there are, is it pragmatic to skirt them with preconditions?