Can't run a suspend function in a `mapNotNull`...?...
# coroutines
d
Can't run a suspend function in a
mapNotNull
...? It might be nice to add such extensions in kotlinx.coroutines that take suspend lambdas no (I don't know how this would work though)? Or use inline functions...
w
This works for me quickly:
Copy code
@Test
    suspend fun doThing() {
        val listOfNumbers = listOf(1,null,null,4,5,6)
        
        listOfNumbers.mapNotNull { 
            alterInt(it)
        }
    }
    
    private suspend fun alterInt(number: Int?): Int? {
        return number?.let {
            delay(500)
            number + number
        }
    }
Or at least, the compiler doesn’t complain
m
Yeah, I just tried this out and it worked for me too.
Copy code
suspend fun doRequest(n: Int): Int? = 
    n.takeIf { n % 2 == 0 }
     .also { delay(100) }

fun CoroutineScope.work() = launch {
    val responses = (0..5).mapNotNull {
        doRequest(it)
    }

    println(responses)
}


suspend fun main() {
    coroutineScope {
        work()
    }
}
d
Try adding
asSequence()
When you have longer chains, it's not so great to create a new list at each step...
e
Unfortunately, suspending in sequence ops is not supported, since sequences are synchronous.
d
@elizarov I was wondering if I'm already in a suspend function making such a chain couldn't it be possible to use it's context to run such functions somehow?
Maybe an coroutine supported implementation of
TransformingSequence
That way they stay synchronous, but suspend during the chain...
m
Because sequences are lazy, the suspension point wouldn't actually be where you call
mapNotNull
. It would be at the point where you do the terminal operation.
And because you can pass sequences around anywhere, that could be in a non-suspending function.
d
Oh, so this is really a cold channel use case... I get it. Thanks!
I wonder how soon cold channels will be implemented... is there some kind of blockage?
e
Indeed, this is a use-case for cold channels