groostav
07/03/2019, 6:46 PMSequence
that work for suspend
contexts? IE i have a sequence and I want to map
on it in a suspend
callerbloder
07/03/2019, 7:08 PMFlow
comes to supply this need, no?groostav
07/03/2019, 7:57 PMmap
calls to happen lazily instead of eagerlybdawg.io
07/03/2019, 8:28 PMmap
operations on a Sequence will still happen lazily. They just will be blocking on each element that's transformed.bloder
07/03/2019, 9:37 PMclass ConcurrentSequence<T>(val sequence: Sequence<T>) : CoroutineScope by CoroutineScope(Dispatchers.Unconfined)
suspend fun <T, R> ConcurrentSequence<T>.map(transform: (T) -> R): ConcurrentSequence<R> = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
ConcurrentSequence(sequence.map(transform))
}
suspend fun <T> ConcurrentSequence<T>.first(): T = sequence.first()
fun <T> concurrentSequenceOf(vararg elements: T): ConcurrentSequence<T> = ConcurrentSequence(elements.asSequence())
bdawg.io
07/03/2019, 10:21 PMwithContext(<http://Dispatchers.IO|Dispatchers.IO>)
block returns immediately though. There's no reason to have the map
function itself suspend. It's an intermediate and a stateless function that doesn't cause the sequence to be evaluatedbloder
07/03/2019, 10:28 PMbdawg.io
07/03/2019, 10:30 PMtoList
or iterating over the sequence) needs to be suspending. Sequence piggy-backs off of the JVM Iterator which doesn't support suspend
, making it blocking to iterate over the sequence using the iterator. Since a sequence operator directly uses the Iterator provided by the previous Sequence in the chain, you'll only have blocking evaluation of sequences. For example, sequence.filter { ... }.map { ... }
, the map
operator uses the Iterator of elements provided by the filter
operator. As such, even writing a different map
extension function that accepts a suspending transform
method will still be blocking because of the iterator from filter
Flow
is a completely separate API from Sequence
, because to have concurrent evaluation, you have to no longer depend on the core mechanism that sequences were built on (JVM iterators that are only blocking)bloder
07/03/2019, 10:52 PMbdawg.io
07/04/2019, 1:11 PMSequence<Deferred<T>>
and then do a terminal operator that fires of all of the coroutines and then perform an await.
coroutineScope {
sequence.map { value ->
async { doSomethingSuspend(value) }
}.toList().awaitAll()
}
It wouldn't fit the "potentially infinite" aspect of sequences.