Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the *Async naming convention for functions returning Deferreds?

Intellij has an inspection (i.e. lint check) that tells you functions that return Deferred should be named something ending in Async.

enter image description here

Naming conventions like these make sense to me in dynamically typed languages. But Kotlin has such a nice type-checker and ecosystem of tooling, so why rely on the convention?

Especially because Kotlin coroutines bake structured concurrency in, the function will probably also take a CoroutineScope parameter, which would serve the same visual cue at the call site:

suspend fun doStuff() = coroutineScope {
  doStuffAsync(this /* CoroutineScope */).await()
  //...
}

As a side note, I understand the inspection's message that you'd rarely want a function that returns a Deferred instead of a suspend function. That's not my question. My question assumes that you know what you're doing and you want a Deferred.

like image 385
aaronstacy Avatar asked Mar 11 '19 18:03

aaronstacy


People also ask

Should I use Async or async modifier for methods returning Task?

By convention, you append "Async" to the names of methods that have an Async or async modifier. Which doesn't even mention that your own asynchronous methods returning Task need the Async suffix, which I think we all agree they do. So the answer to this question could be: both.

What is the return type of async async?

Async methods can have the following return types: Task<TResult>, for an async method that returns a value. Task, for an async method that performs an operation but returns no value. void, for an event handler. Starting with C# 7.0, any type that has an accessible GetAwaiter method.

What happens if the async function returns a promise?

If the function that contains the asynchronous task returns a promise, the asynchronous operation will block just that function. Now, how do you handle async functions that return values?

What is the Convention for suffixing method names with “async”?

What is the convention for suffixing method names with "Async". The Task-based Asynchronous Pattern (TAP) dictates that methods should always return a Task<T> (or Task) and be named with an Async suffix; this is separate from the use of async.


1 Answers

To begin with, a function should almost never return a Deferred that comes from an async block. It is up to the caller to wrap some unit of work into an async while doing other work in the foreground, then await on the async result before returning, and wrap all that code in a coroutineScope.

The intended source of Deferred instances is the adaptation layer between Kotlin coroutines and 3rd-party async APIs. For such calls it does make sense to put Async in the name and even some Java APIs follow this convention. For example, you may have a

fun fetchOrder(id: String): Deferred<Order>

and use it as

val orderCancelled = fetchOrder(orderId).isCancelled

This code is type-safe and type-correct, it doesn't cause any compiler errors. It looks like it's fetching an order from a remote system and then checking the order status (whether it's cancelled), but what it's actually doing is getting a Deferred<Order> and checking whether the Deferred is cancelled. Because your function name is missing Async, this kind of error is hard to spot.

Yes, you can also request the IDE to give you the return type, but it may take a while before you even suspect what's going on.

like image 186
Marko Topolnik Avatar answered Oct 18 '22 20:10

Marko Topolnik