Skip to content

valbaca/gotlin

Repository files navigation

gotlin

Structured concurrency from The Go Programming Language code reimagined/reimplemented in Kotlin coroutines

fun gotlin(go): kotlin

Why?

Go's goroutines and Kotlin's coroutines have a lot in common (and only one letter different)!

While learning Kotlin I struggled a bit with understanding coroutines in a way that I didn't when learning goroutines.

When I learned about Kotlin's select I realized I could fully re-apply my goroutine knowledge. I don't have a Kotlin coroutine book on my shelf, but I do have "The Go Programming Language"

So, for my own self-elucidation (and hopefully others as well!) I began rewriting the examples in Kotlin.

I found Kotlin coroutines online quite lacking, so hopefully this helps improve that by proxy.

Caveats

  1. This is NOT production code. I don't do great error handling and the code is probably terrible.
  2. I'm still new to Kotlin. I did this as a part of learning Kotlin. See point #1
  3. Coroutines are available in Kotlin via kotlinx-coroutines-core. Coroutines aren't a part of the core language like goroutines are in Go.
  4. I first used http4k as a substitute for Go net/http for requests and server. Later on I started using Ktor

Of course: if you've got suggestions, please create Pull Requests!

Things I've learned

  1. See the Coroutine extension pattern below
  2. Kotlin's Channels throw exceptions if read from after close. Go's channels return zero-value.
  3. Kotlin's select is implemented as a DSL and has some differences from Go's select:
    • If multiple cases are valid, Kotlin biases toward the first whereas Go will pick at random.
    • Kotlin's select doesn't have a default
  4. Rather than using object{} which is akin to Go's struct{}{}, Kotlin can instead use Unit for channels that only process signals without any content.
  5. Kotlin has whileSelect which replaces Go's for { select { infinite-loop pattern.

Coroutine extension pattern

I learned this pattern from: Kotlin Coroutines in Practice. In-fact, that talk directly inspired me to work on this.

import kotlin.coroutines.CoroutineContext

// Take a function...
fun fn() {
    /* do fn stuff */
}

// ...and simply change the first line to the following

fun CoroutineContext.fn() = launch {
    /* do fn stuff */
}

// ... and now you can call it within any coroutine scope and it will launch a coroutine


fun main() = runBlocking {
    fn() // now this is semi-equivalent to `go fn()` in Go
}

Links that were useful to me

License

In no way do the authors of "The Go Programming Language" endorse this or this use.

These examples are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Creative Commons License

About

Kotlin Coroutine examples inspired by Go's Goroutines

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages