Pitch [stdlib]: making sorting algorithm selectable

I meant something like this response:

Having gone through this pitch, I would like to bump it saying that just having the option to provide a custom sorting algorithmn is a good one. Let the onus of providing the actual sorting algorithmn be up to the user but the interface & the building blocks be included in the standard library itself.

Intuitive Example:

[5,4,10,1,6,2].sorted(using: BubbleSort(), by: >)

The usage of providing custom sort algorithmns indeed may be rare but the standard library would atleast have that flexibility out-of-the-box.
The above style would be similar to Combine's .decode(type:decoder:) operator that accepts a TopLevelDecoder to do the real decoding:

.decode(Model.self, JSONDecoder())

One might argue but it's also rare that someone will implement their own TopLevelDecoder. Yet... that flexibility is available to us all.


Implementation:

protocol Sorter {
    typealias OrderingHandler<Element> = (Element, Element) throws -> Bool
    func sort<Element>(_ array: inout [Element], by areInIncreasingOrder: OrderingHandler<Element>) rethrows
}

extension Array {
    mutating func sort(using sorter: Sorter, by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows {
        try sorter.sort(&self, by: areInIncreasingOrder)
    }
    
    func sorted(using sorter: Sorter, by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element] {
        var array = self
        try array.sort(using: sorter, by: areInIncreasingOrder)
        return array
    }
}

Usage:

class BubbleSort: Sorter {
    func sort<Element>(_ array: inout [Element], by areInIncreasingOrder: OrderingHandler<Element>) rethrows {
        print("Bubble Sort")
    }
}

class InsertionSort: Sorter {
    func sort<Element>(_ array: inout [Element], by areInIncreasingOrder: OrderingHandler<Element>) rethrows {
        print("Insertion Sort")
    }
}

//Sort Approach
var array = [5,4,10,1,6,2]
array.sort(using: BubbleSort(), by: >)

//Sorted Approach
[5,4,10,1,6,2].sorted(using: InsertionSort(), by: >)

Thanks for writing this pitch! This feature is needed a lot for Server Side Swift.

Can somebody tell, if standard library do some heuristics to choose best algorithm, depending on elements count for example?
Sorting 10_000, 1_000_000, and 100_000_000 of elements needs different algorithms.

How about telling the stdlib what properties you need, and stdlib choosing the fastest implementation for you?

array.sort(properties: [.stable, .inPlace])

Some combinations would be impossible, but that could be checked if/when we have static assertions Compile-Time Constant Expressions for Swift

If having support on stdlib level, what @cukr suggests above seems like the only reasonable exposure of interface IMHO. As previously mentioned, it seems like a bad idea to commit to exposing specific algorithms. If specifying sort algo properties, it allows for the implementation to change (for the better :-) over time.

1 Like