robin
10/16/2018, 3:01 PMsuspend fun main(args: Array<String>) = runBlocking {
val unsorted = generateSequence { Random.nextInt() }.take(200)
val sortedChannel = Channel<Int>()
val sorted = sequence { for (msg in sortedChannel) yield(msg) }
unsorted.map { async { delay(it * 10L); sortedChannel.send(it) } }
sorted.forEach(::println)
}
But I'm getting an error about restricted suspending functions where I'm iterating over the channel. Can anyone tell me what that's about?Zach Klippenstein (he/him) [MOD]
10/16/2018, 3:07 PMmap
on a sequence, not a list. If you look at the implementations of the map operator map, you'll see it's an inline function - that's why it works from suspend functions, because the code is effectively just copied into the call site. List.map can be inline (as well as it's map function) because it executes immediately (as soon as you run map it gives you a copy of the list with the mapped elements).
Sequences are lazy though. So when you call map on a sequence, it doesn't execute anything immediately. It stores the map function so that when you need to iterate over the sequence later, it can call it then. Because it's storing the map function, it can't be inlined, so it's just storing the actual function, which isn't marked as suspendable.robin
10/16/2018, 3:08 PMsequence
is actually marked as suspendZach Klippenstein (he/him) [MOD]
10/16/2018, 3:09 PMmap
isn't though.Zach Klippenstein (he/him) [MOD]
10/16/2018, 3:09 PMrobin
10/16/2018, 3:10 PMmap
is compiling, it's the line before that I'm wondering aboutrobin
10/16/2018, 3:11 PMZach Klippenstein (he/him) [MOD]
10/16/2018, 3:11 PMZach Klippenstein (he/him) [MOD]
10/16/2018, 3:12 PMrobin
10/16/2018, 3:13 PMZach Klippenstein (he/him) [MOD]
10/16/2018, 3:13 PMZach Klippenstein (he/him) [MOD]
10/16/2018, 3:13 PMrobin
10/16/2018, 3:15 PMZach Klippenstein (he/him) [MOD]
10/16/2018, 3:33 PMsortedChannel.toList()
Zach Klippenstein (he/him) [MOD]
10/16/2018, 3:33 PMrobin
10/16/2018, 3:37 PMrobin
10/16/2018, 3:38 PMsuspend fun main(args: Array<String>) = runBlocking {
val unsorted = List(50) { Random.nextInt(100) }
val sortedChannel = Channel<Int>()
launch {
unsorted
.map { launch { delay(it * 10L); sortedChannel.send(it) } }
.forEach { it.join() }
sortedChannel.close()
}
println(sortedChannel.toList())
}
Zach Klippenstein (he/him) [MOD]
10/16/2018, 3:52 PM