Kotlin alternative to Python's coroutine yield and send

dmzkrsk

What would be a Kotlin idiomatic alternative to the following python coroutine snippet:

def generator():
  c = 1
  while True:
    op = yield c
    if op == 'inc':
      c += 1
    elif op == 'mult':
      c *= 2

# main
g = generator()
a = g.send(None) # start
b = g.send('inc')
c = g.send('mult')
d = g.send('inc')

print([a, b, c, d]) # 1, 2, 4, 5

So I need get values from the coroutine (via a channel?), but also send the values back into the coroutine. Do I need two channels for that?

Roman Elizarov

Two-way generators of the kind that are present in Python and in ES6 are not really idiomatic in Kotlin, because Kotlin is a statically typed language and therefore two-way generators are quite clumsy to use. Just take a look at the g.send(None) in the above code to understand why it is so. So, implementation of two-way generators is not provided in Kotlin standard library nor in supporting libraries.

However, coroutines support in Kotlin language is generic enough and two-way generators can be implemented, if needed, to behave just like in Python and ES6. The corresponding implementation is available here and takes just a few dozen lines of code.

With the above implementation of two-way generator, your Python code can be directly translated into Kotlin line-by-line:

fun generator() = generate<Int, String> {
    var c = 1
    while (true) {
        val op = yield(c)
        when (op) {
            "inc" -> c += 1
            "mult" -> c *= 2
        }
    } 
}

fun main(args: Array<String>) {
    val g = generator()
    val a = g.next("") // start
    val b = g.next("inc")
    val c = g.next("mult")
    val d = g.next("inc")
    println("$a $b $c $d") // 1, 2, 4, 5
}

This code works just as well as its Python version, however it is not idiomatic for multitude of reasons. For one, is that coroutines support in Kotlin allows for definition of arbitrary suspending functions and thus makes it possible to express similar behaviour in a type-safe way without resorting to an arbitrary start marker nor using strings to denote operations. You can straightforwardly define an object that has inc and mult as its first-class suspending operations, or, at least, change implementation so that a dummy start invocation is not needed. You are welcome to study coroutines design document that explains all the low-level primitives that Kotlin provides and has a number of examples to get you started.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Does Kotlin's launch start a coroutine in the main or a background thread?

分類Dev

"yield" in Python

分類Dev

How to call Kotlin coroutine in composable function callbacks?

分類Dev

Kotlin coroutine list returning null value

分類Dev

Returning from inner nested coroutine by label Kotlin

分類Dev

python generator yield for a file

分類Dev

What is a faster alternative to Python's http.server (or SimpleHTTPServer)?

分類Dev

How to use yield function in python

分類Dev

combine yield with if/else loop in python

分類Dev

KotlinのCOROUTINE_SUSPENDEDおよびsuspendCoroutineOrReturn

分類Dev

how to use Coroutine in kotlin to call a function every second

分類Dev

Suspending a Kotlin coroutine until a flow has a specific value

分類Dev

Python alternative to global variables

分類Dev

Is there an alternative to Google's JOBB tool?

分類Dev

What's the alternative for TensorFlow VocabularyProcessor?

分類Dev

Alternative for Chrome's Coverage in Firefox

分類Dev

Porting from Ruby to Python: What to do with 'yield'

分類Dev

Alternative way to send email without getting "Suspicious sign in prevented"

分類Dev

Trying to send "alternative" with MIME but it also shows up in capable mail client

分類Dev

How can I catch an exception in Kotlin coroutine when I am awaiting it in another function?

分類Dev

Can I send parameter to the Interface in kotlin?

分類Dev

python-yield(yield)は何をしますか?

分類Dev

Laravel's @yield inside html tag for blade view engine

分類Dev

PHPのYIELD-> send()は誰が機能しますか?

分類Dev

Kotlin-コルーチンyield()その目的は何ですか?

分類Dev

python datetime fromtimestamp yield valueerror year out of range

分類Dev

NoneType-Pythonでのyieldのエラー

分類Dev

How do I obtain results from 'yield' in python?

分類Dev

Pythonジェネレーター-float((yield))?

Related 関連記事

  1. 1

    Does Kotlin's launch start a coroutine in the main or a background thread?

  2. 2

    "yield" in Python

  3. 3

    How to call Kotlin coroutine in composable function callbacks?

  4. 4

    Kotlin coroutine list returning null value

  5. 5

    Returning from inner nested coroutine by label Kotlin

  6. 6

    python generator yield for a file

  7. 7

    What is a faster alternative to Python's http.server (or SimpleHTTPServer)?

  8. 8

    How to use yield function in python

  9. 9

    combine yield with if/else loop in python

  10. 10

    KotlinのCOROUTINE_SUSPENDEDおよびsuspendCoroutineOrReturn

  11. 11

    how to use Coroutine in kotlin to call a function every second

  12. 12

    Suspending a Kotlin coroutine until a flow has a specific value

  13. 13

    Python alternative to global variables

  14. 14

    Is there an alternative to Google's JOBB tool?

  15. 15

    What's the alternative for TensorFlow VocabularyProcessor?

  16. 16

    Alternative for Chrome's Coverage in Firefox

  17. 17

    Porting from Ruby to Python: What to do with 'yield'

  18. 18

    Alternative way to send email without getting "Suspicious sign in prevented"

  19. 19

    Trying to send "alternative" with MIME but it also shows up in capable mail client

  20. 20

    How can I catch an exception in Kotlin coroutine when I am awaiting it in another function?

  21. 21

    Can I send parameter to the Interface in kotlin?

  22. 22

    python-yield(yield)は何をしますか?

  23. 23

    Laravel's @yield inside html tag for blade view engine

  24. 24

    PHPのYIELD-> send()は誰が機能しますか?

  25. 25

    Kotlin-コルーチンyield()その目的は何ですか?

  26. 26

    python datetime fromtimestamp yield valueerror year out of range

  27. 27

    NoneType-Pythonでのyieldのエラー

  28. 28

    How do I obtain results from 'yield' in python?

  29. 29

    Pythonジェネレーター-float((yield))?

ホットタグ

アーカイブ