I'm new to Kotlin, and asynchronous programming doesn't seem that simple here.
In fact, Kotlin takes it to the next level of simplicity: it's almost invisible. For example:
suspend fun main() {
println("Hello")
delay(1000)
println("Hello again")
}
This code, unbeknownst to you, is actually implemented as asynchronous. But you just see simple, sequential code. The compiled code (in case of the JVM backend) has structure something like this:
public static void main(String[] args) {
System.out.println("Hello");
globalThreadPool.scheduleAfterDelay(() -> {
println("Hello again");
}, 1000, TimeUnit.MILLISECONDS);
}
On top of that, Kotlin makes it super-simple to adapt any async code you may have today so that you can use in the same native way as the above built-in delay
function.
Where people trip up mostly is not this basic scenario, but dealing with more advanced topics like structured concurrency, choosing the right thread pool to run your code, error propagation, and so on.
I haven't studied Dart, but from what I know about the async-await pattern in other languages, whenever you call an async
function, you have implicitly created a concurrent task, which is very easy to leak out -- all it takes is forgetting to await
on it. Kotlin prevents these bad outcomes by design and forces you to address the concurrency you're creating head-on, instead of decyphering out-of-memory logs from production.