Asynchronous programming with Kotlin and Coroutines— Lesson 1: Routines

Filip Babic
Background Thread
Published in
5 min readJul 17, 2018

Note: Make sure to check out my other articles in this series:

Some programming concepts are truly hard. Or at least they are at first glance. When thinking about how code is compiled and programs are executed, human mind can easily comprehend sequential like computing. But in reality, nothing bar the simplest of programs manifests in a single-threaded environment, at least in mobile applications.

However, when we start learning asynchronous programming, just by the very fact that we’re not used to things happening sometimes in the future, unexpected, we suffer tremendous cognitive load.

Which is why I’ve taken up writing this series, in hopes that terms like routines, continuations, computation, coroutines and many more, will be brought closer to you, by simple, everyday examples.

Routines

Merely delving into code wouldn’t yield much result, as it’s better to understand the foundation of asynchronous programming and why it’s paramount to all forms of software.

We’ll start off by learning what Routines are. Think of your day-to-day life. Even if you’re not a creature of habit, you’re subject to some form of a routine. You get up at a certain hour most days, either have breakfast, with your favourite beverage, or skip breakfast at all (which is bad!). Then you proceed to your daily chores, job, school or some other form of activity to fill your day.

Analysing that morning, it’s pretty much a routine. It’s something that has a beginning and something that eventually ends. In this case it starts by waking up and ends by moving on to some more important activity.

Just like in life, computer programming has it’s own routines. Mostly they start by opening an application or running a program, and end by closing the app or when the program finishes. For the sake of optimism, we’ll stick to the happy paths in this lesson.

Each routine, or more specifically subroutine, as such represents a unit which is being executed. It can be accessed through multiple points in code (for example a function can be called at different places) but it always finishes with a return statement, and it can produce a value or some side effects.

Inside the subroutine the program execution changes it’s context, this is often called scoping in programming. By accessing a different context or scope you gain access to whatever is available in that scope, but it becomes unusable once you leave.

Another thing about subroutines is that they’re computed and processed sequentially and they block further instructions until the current subroutine is done.

Looking at the morning analogy, when you start waking up, you can’t do anything else until you wake up. Waking up would be a blocking routine, which when done proceeds with another task. It can be accessed from multiple points (as you can fall asleep anywhere), and when in the waking up routine, you have access to your surroundings, or the context, such as your current bed and the annoying alarm.

This would be represented as the following, in Kotlin code:

fun wakeUp() {
getUp(bed) //only after we're up, can we turn the alarm off
alarmClock.turnOff() //we need silence that annoying alarm
}

From the simple snippet above, you can see the aforementioned concepts in action. Blocking calls with getUp(bed) and alarmClock.turnOff() are made. Until each of the said subroutines is finished, we cannot conclude waking up.

Also the bed and alarmClock values are available to us when waking up. In this case those are fields of the surrounding class/function. They could’ve also been sent as parameters. Either way, they make up the context of our routine.

Routine family tree

Just like a program or a process has to be started from another process, and it can start other processes, so can a routine, once started by another routine, generally the main program, start other routines.

Once again, tracing back to the breakfast routine, when you start to make breakfast it’s actually a bigger routine composed of smaller ones. You first have to start a routine in which you make toast. First grab a couple slices of toast. Then you proceed to put some butter on it and finally you finish the toast-making-routine by putting everything in a toaster.

In code, it would be described as such:

fun makeBreakfast() {
val butter = Butter() //subroutines which build our objects
val toast = Toast()

toast.addButter(butter) //subroutine which adds some butter

val crispyToast = toaster.makeToast(toast) //toasting subroutine

eat(crispyToast) //we pass the toast to another subroutine
}

Where the toaster.makeToast(toast) subroutine looks like this:

fun makeToast(toast: Toast): CrispyToast {
startTheTimer()
val crispyToast = bakeToast(toast)

stopTimer()

return crispyToast
}

Every subroutine child is bolded out. It’s important to note that every subroutine can have as many children routines as it can create. But it can only ever have one parent routine. If we were to draw out the call structure here it would look like this:

Breakfast routine tree

You can see that each of the child routines can have it’s own children, to whom they are parent, creating a family-tree-like structure. Tree structures are well known in computer science, as they are used to represent quite a lot of things. Our tree could’ve had a lot more layers and nodes, or at least as much as the stack limit allows.

Conclusion

Subroutines as such are powerful in programming, as they allow you to wrap common behaviour into neat units of execution, which can then be called anytime, and as much as it’s needed. These constructs are mostly called functions, procedures or methods in general.

However, due to limits, like the aforementioned blocking, they are not used for heavy tasks or computation because it may cause the program to stop for an indefinite period of time. This is where asynchronous programming comes handy, but we’ll see what it’s composed of in the next lessons.

Where to go from here

Marin Benčević and I have started a Computer Science publication here on Medium, so if you’ve got any interesting ideas on what we could cover in the future, or have any proposals for articles yourself, be sure to mention it in the comments below, or contact us at Twitter.

And stay tuned for the rest of the series on asynchronous programming, computation and coroutines! :]

Check out my other articles in this series:

--

--

Filip Babic
Background Thread

Android developer. Praise Kotlin :] Keen and enthusiastic learner and mentor, passionate about teaching and helping others. GDE @ Android, Osijek, Croatia.