Here's a draft proposal of introducing a SortedCollection protocol. The proposal doesn't include a concrete type that implements this. However, I wouldn't mind any suggestions for a concrete type, but would valid reasons over any other types.
Sorted Collections
- Proposal: SE-NNNN
- Authors: Letanyan Arumugam
- Review Manager: TBD
- Status: Awaiting implementation
During the review process, add the following fields as needed:
- Implementation: apple/swift#NNNNN
- Decision Notes: Rationale, Additional Commentary
- Bugs: SR-NNNN, SR-MMMM
- Previous Revision: 1
- Previous Proposal: SE-XXXX
Introduction
There are algorithms, and data structures rely on having sorted guarantees. However,
currently, the Swift Standard Library does not provide a way to allow types to
offer this semantic guarantee.
Swift-evolution thread: Discussion thread topic for that proposal
Motivation
Having a common entry point to write algorithms that rely on sorted order guarantees
would be desirable for allowing communication between multiple libraries and
code bases. The Standard Library may also want to provide types that would
require the semantics of this proposal later.
However, the commonality is only useful if the use cases that use the standard entry point are
useful on their own.
Performance
A typical way of improving search performance is to use a binary search which
relies on having a random access collection of sorted elements. Other structures
have structural qualities that inherently allow similar O(log n) performance.
A collection that is updated to be sorted at each entry can be more efficient
than calling sort every time you need to use the collection.
Semantics
It is useful to have a way to represent collections with an inherit sorted order.
Structures such as priority queues, sorted dictionaries and sets have useful
features. Namely displaying results or prioritising information.
Proposed solution
Introducing a protocol that provides the semantic guarantees of having a
collection that is always sorted.
protocol SortedCollection : Collection {
mutating func insert(_ element: Element)
}
Note that there is no requirement for an Element
to be Comparable
. Not
having this requirement allows any conformer to be able to use any way of
providing sorted guarantees.
The proposed solution will provide types to have their elements declare sorting
by their Comparable
conformance or through a closure.
Detailed design
/// A collection that guarantees that the conforming type always has its
/// elements in a given sorted order.
///
/// For example, when elements are inserted into the collection the collection
/// will have them inserted in a order determined by some comparison.
///
/// var xs = SortedArray()
/// xs.insert(5)
/// xs.insert(10)
/// xs.insert(0)
///
/// The order that xs has its elements would be as follows, 0, 5, 10.
protocol SortedCollection : Collection {
/// Inserts an element into correctly corresponding comparative position.
///
/// This method must ensure that any element passed in must be placed in
/// its correct position within the collection. This position can be based
/// on the elements relation using its conformance to Comparable, if such
/// a conformance is available. Or through a closure or some other method
/// that determines the relational order between two elements.
mutating func insert(_ element: Element)
}
Source compatibility
This is purely additive.
Effect on ABI stability
No effect on ABI.
Effect on API resilience
Some types in the Standard Library may adopt this protocol and as such removal
of this would cause specific algorithms that rely on using a SortedCollection
constraint to be modified.
Alternatives considered
Constrain Element to Comparable
This would force collections to force elements to conform to Comparable
if
they weren't. Collections may also want to have custom sorting that only makes
sense for specific scenarios. Take for example a table row, the sorting method is
not an inherent part of any row item, but somewhat situational. Types should be allowed to
provide this flexibility without being restrained.
Require a Sorting Closure
On the other side of requiring Element
to conform to Comparable
is a general
closure. Forcing conformers to fulfil is also undesirable when not
needed, as it forces the conformer to include overhead to a type that
may not require it.