## 1. Overview

In this tutorial, we’ll focus on understanding the **yield function in Kotlin** through some simple use cases.

## 2. Basics

The first thing to know about the *yield()* function is that it is a suspend function that is used in the context of Kotlin Coroutines. When *yield() *is invoked, it **yields the thread (or thread pool) of the current coroutine dispatcher to other coroutines to run if possible**.

Secondly, we should understand that *yield()* and *yield(value: T)* are two different functions. The latter is used only in the context of sequences, as we’ll explore in the next section.

## 3. Building Sequences

One of the most common use cases where we can use *yield()* is to build sequences. So let’s get into action.

### 3.1. Finite Sequence

Let’s say we want to build a finite sequence of vowels. For such a short sequence, we can use multiple statements that yield a single vowel value. Let’s define *vowels()* function in the *Yield* class:

```
fun vowels() = sequence {
yield("a")
yield("e")
yield("i")
yield("o")
yield("u")
}
```

Now, let’s do an iteration over this sequence using a *vowelIterator:*

```
val client = Yield();
val vowelIterator = client.vowels().iterator()
while (vowelIterator.hasNext()) {
println(vowelIterator.next())
}
```

Once we run our main function, we should be able to validate the result of the iteration. In this simple scenario, an important thing to note about finite sequences is that we should always **use the ***hasNext()* method to check whether there is a next item available in the sequence before invoking the *next()* method of *vowelIterator*.

### 3.2. Infinite Sequence

A more practical use case of using *yield()* is to build infinite sequences. So, let’s use it to generate terms of a Fibonacci sequence.

To build such a sequence, let’s write a *fibonacci()* function that uses an infinite loop yielding a single term in each iteration:

```
fun fibonacci() = sequence {
var terms = Pair(0, 1)
while (true) {
yield(terms.first)
terms = Pair(terms.second, terms.first + terms.second)
}
}
```

Now, let’s verify the first five terms of the sequence by using an iterator for this sequence:

```
val client = Yield();
val fibonacciIterator = client.fibonacci().iterator();
var count = 5
while (count > 0) {
println(fibonacciIterator.next())
count--;
}
```

For infinite sequences, **we can relax the call to the ***hasNext()* method of the iterator as we’re guaranteed to get the next element of the sequence.

## 4. Cooperative Multitasking

In a cooperative multitasking system, a task would voluntarily yield to allow another job to execute. In this section, we’ll use the *yield()* function to achieve cooperative multitasking in a simple system.

### 4.1. Number Printer Orchestrator

Let’s say we want to print all numbers below a specific threshold value.

First, let’s define the *current* value as *0* using an *AtomicInteger* and *threshold* as a constant integer value:

```
val current = AtomicInteger(0)
val threshold = 10
```

Now, let’s define a *numberPrinter()* function to orchestrate the printing of the numbers.

We intend to **divide and conquer by defining two different jobs, one for printing even numbers and the other one for printing odd numbers**. So, to ensure that we’re waiting until all numbers below the threshold are printed, we’ll define it with the *runBlocking* CoroutineScope:

```
fun numberPrinter() = runBlocking {
}
```

### 4.2. Odd-Even Number Printer

Now, let’s focus on the part where we’ll delegate the task of printing numbers to two different jobs, namely *evenNumberPrinter* and *oddNumberPrinter.*

First, let’s see how we can launch an *evenNumberPrinter* job:

```
val evenNumberPrinter = launch {
while (current.get() < threshold) {
if (current.get() % 2 == 0) {
println("$current is even")
current.incrementAndGet()
}
yield()
}
}
```

The idea is straightforward; it is printing the current value only when it’s even. Otherwise, **it understands that it needs to cooperate with another task that can print the odd values, so it voluntarily yields**.

Next, let’s look into the *oddNumberPrinter* job, which is essentially the same except for the condition where it prints only odd numbers:

```
val oddNumberPrinter = launch {
while (current.get() < threshold) {
if (current.get() % 2 != 0) {
println("$current is odd")
current.incrementAndGet()
}
yield()
}
}
```

Finally, let’s call the *numberPrinter()* orchestrator to print the numbers:

`client.numberPrinter()`

As expected, we’re able to see all the numbers below the *threshold*:

```
0 is even
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
```

## 5. Conclusion

In this tutorial, we took a **hands-on approach **to understand the *yield *function in Kotlin by **building sequences and achieving cooperative multitasking of jobs**.

As always, the source code is available over on GitHub.