Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes Iterable.map work with suspend functions?

In general, suspend funs cannot be used in place of normal funs. If you try to call a suspend fun directly from a normal fun, you will get a compile-time error.

This blog post mentions that you can do a concurrent map in Kotlin by writing

list.map { async { f(it) } }.map { it.await() }

Why does the second map compile? You can't generally pass a suspend fun in place of a fun. Is it

  • that map is an inline fun and that the suspension is automatically inferred "upstream"
  • that map is special cased somehow by Kotlin
  • something else?
like image 498
Louis Wasserman Avatar asked Jun 20 '19 21:06

Louis Wasserman


People also ask

How does suspend function work?

A suspending function is simply a function that can be paused and resumed at a later time. They can execute a long running operation and wait for it to complete without blocking. The syntax of a suspending function is similar to that of a regular function except for the addition of the suspend keyword.

How does coroutine suspension work?

With coroutines, it just suspends and gives the library a continuation with the instruction "Once you've got this data, just send it to the resume function". Then the thread can go do other things. Once the data is there, the thread will be used to resume from the point where the coroutine was suspended.

What is the use of Suspend?

Suspend function is a function that could be started, paused, and resume. One of the most important points to remember about the suspend functions is that they are only allowed to be called from a coroutine or another suspend function.

How do you use await in Kotlin?

In order to migrate to the async/await pattern, you have to return the async() result from your code, and call await() on the Deferred , from within another coroutine. By doing so, you can remove callbacks you used to use, to consume asynchronously provided values.


1 Answers

that map is an inline fun and that the suspension is automatically inferred "upstream"

Yes. Suspend funs are checked after inlining. I can't see an explicit mention of this in documentation, but there is one in the Coroutines KEEP:

Note: Suspending lambdas may invoke suspending functions in all places of their code where a non-local return statement from this lambda is allowed. That is, suspending function calls inside inline lambdas like apply{} block are allowed, but not in the noinline nor in crossinline inner lambda expressions. A suspension is treated as a special kind of non-local control transfer.

like image 54
Alexey Romanov Avatar answered Sep 27 '22 22:09

Alexey Romanov