https://kotlinlang.org logo
#compiler
Title
# compiler
a

Andrey Navodnik

11/22/2023, 10:19 AM
Hi everybody, I have created a simple program
executeAsync1()
with the following parameters:
Copy code
import kotlinx.coroutines.Dispatchers
import kotlin.coroutines.CoroutineContext

// (A)
fun executeAsync1(
    vararg executors: suspend () -> Unit,
    context: CoroutineContext = Dispatchers.IO,
 ) {}

fun testA() {
    executeAsync1(
        { println("ABC") },
        { println("XYZ") },
    )
}
Program compiles and everything is OK. But if I change the order of parameters, as could be seen from the following code snippet
Copy code
// (B)
fun executeAsync2(
    context: CoroutineContext = Dispatchers.IO,
    vararg executors: suspend () -> Unit,
) {}

fun testB() {
    executeAsync2(
        { println("ABC") },
        { println("XYZ") },
    )
}
then I get an error message:
Copy code
Type mismatch.
Required: CoroutineContext
Found: () → Unit
Is there any particular reason why the second combination (B) should not be allowed? I mean, although the
context
parameter has a default value, it must be explicitly specified before
vararg
parameters, as follows:
Copy code
fun testC() {
    executeAsync2(
        context = Dispatchers.IO,
        { println("ABC") },
        { println("XYZ") },
    )
}
j

Johann Pardanaud

11/22/2023, 10:33 AM
see: https://kotlinlang.org/docs/functions.html#default-arguments
If a default parameter precedes a parameter with no default value, the default value can only be used by calling the function with named arguments:
```fun foo(
bar: Int = 0,
baz: Int,
) { /*...*/ }
foo(baz = 1) // The default value bar = 0 is used```
Of course, there is the following statement:
If the last argument after default parameters is a lambda, you can pass it either as a named argument or outside the parentheses:
But it seems that it doesn't apply to varargs
a

Andrey Navodnik

11/22/2023, 10:54 AM
@Johann Pardanaud thank you for your answer and pointing out the documentation. It seems to me, that in the second case (B) the
vararg
parameter must be explicitly named:
Copy code
fun testC() {
    executeAsync2(
        executors = arrayOf(
            { println("ABC") },
            { println("XYZ") }
        ),
    )
}
j

Johann Pardanaud

11/22/2023, 10:55 AM
yes, that's required in this case
2 Views