#coroutines
Title
# coroutines
b

bloodshura

06/27/2021, 4:12 PM
How'd I go implementing a
``List#sortedWith``
that takes a comparator which can be suspended? Suppose I'd need something like this:
Copy code
``someList.sortedWith { o1, o2 -> suspendedComparison(o1, o2) }``
Where
``suspendedComparison``
is a function which returns
``Int``
(satisfying
``Comparator``
) and is a
``suspend fun``
...
This, as is, won't work because
``sortedWith``
takes a
``Comparator``
as an argument, whose SAM is not suspendable. But then, what are the alternatives? Will I need to implement a sorting algorithm from scratch just to make it suspendable?
m

mbonnin

06/27/2021, 4:21 PM
Most likely not the answer you expected but you can wrap your
``suspendedComparison``
in
``runBlocking {}``
👍 1
b

bloodshura

06/27/2021, 4:25 PM
Yeah haha, I'm looking for something that would not block, since these suspended comparisons could take some time (even seconds)...
m

mbonnin

06/27/2021, 4:28 PM
I'm not sure there's a way to "rewrite" a regular function into a suspendable one
Maybe with some IR-compiler-plugin magic ?
That sounds involved though...
e

ephemient

06/27/2021, 5:42 PM
if performance isn't a major concern as you'll be waiting for your comparator anyway, rolling your own sort is easy enough:
Copy code
``````suspend fun <T> List<T>.sortedWith(comparator: suspend (a: T, b: T) -> Int): List<T> {
if (size <= 1) return this
val first = first()
val (left, right) = drop(1).partition { comparator(first, it) >= 0 }
return left.sortedWith(comparator) + first + right.sortedWith(comparator)
}``````
❤️ 1
heck you could even parallelize it:
Copy code
``````suspend fun <T> List<T>.sortedWith(scope: CoroutineScope, comparator: suspend (a: T, b: T) -> Int): List<T> {
if (size <= 1) return this
val first = first()
val (left, right) = drop(1).partition { comparator(first, it) >= 0 }
val sortedLeft = scope.async { left.sortedWith(this, comparator) }
val sortedRight = scope.async { right.sortedWith(this, comparator) }
return sortedLeft.await() + first + sortedRight.await()
}``````
you're not going to be able to magically make the existing sort method suspending. it boils down to re-using platform's (e.g. Java, JS) standard library sort
K/N does have its own sort implementation so you could copy that, but it's a bit fancier than the ⬆️ dumb quicksort above https://github.com/JetBrains/kotlin-native/blob/master/runtime/src/main/kotlin/kotlin/collections/ArraySorting.kt
👀 1
b

bloodshura

07/01/2021, 6:53 PM
Thank you very much!
4 Views