I don't see a very clear definition of the yield
function in Kotlin.
Example in the link above doesn't mention much but the following,
val sequence = sequence { val start = 0 // yielding a single value yield(start) // yielding an iterable yieldAll(1..5 step 2) // yielding an infinite sequence yieldAll(generateSequence(8) { it * 3 }) } println(sequence.take(7).toList()) // [0, 1, 3, 5, 8, 24, 72]
But the above example doesn't point out the significance of yield.
Yields a value to the Iterator being built and suspends until the next value is requested.
Yields a thread (or thread pool) of the current coroutine dispatcher to other coroutines to run. If the coroutine dispatcher does not have its own thread pool (like Dispatchers. Unconfined) then this function does nothing, but checks if the coroutine Job was completed. This suspending function is cancellable.
A coroutine internally uses a Continuation class to capture the contexts for its execution. Then the dynamic aspect is modeled as a Job class. The use of async usually creates a Deferred job, which is a subclass of the Job class. The CoroutineContext type is required for a coroutine to execute.
A sequence is a container Sequence<T> with type T. It's also an interface, including intermediate operations like map() and filter(), as well as terminal operations like count() and find(). Like Streams in Java, Sequences in Kotlin execute lazily.
You can think of yield()
as "return, and next time start from where you stopped":
val sequence = sequence { val start = 0 yield(start) // first return yieldAll(1..5 step 2) // if called again, will start from here yieldAll(generateSequence(8) { it * 3 }) // if called more that six times, start from here }
It creates state machine and stuff, but you can translate it to something like following in Java:
class Seq { private AtomicInteger count = new AtomicInteger(0); private int state = 0; public int nextValue() { if (count.get() == 0) { return state; } else if (count.get() >= 1 && count.get() <= 5) { state += 2; return state; } else { state *= 3; return state; } } }
In Java class we maintain explicit state by having two variables: count
and state
. Combination of sequence
and yield
allow this state to be maintained implicitly.
Note that yield()
is a suspending function, so it may be invoked only from another suspend
function or from within a coroutine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With