Hi everybody, I want you to look at the following...
# getting-started
a
Hi everybody, I want you to look at the following code snippet:
Copy code
fun main() {
    val array = listOf("a", "b", "c").toTypedArray()
    doAction(*array) // (1)
}

tailrec fun doAction(vararg items: String) {
    when (items.size) {
        0 -> return
        else -> {
            val array = items.drop(1).toTypedArray()
            doAction(*array) { // (2)
                println(items.first())
            }
        }
    }
}
The question is not about weather this piece of code is written efficiently (probably not) or this pattern should be allowed (probably not). It is about error message, because compiler emits an error message "Passing value as a vararg is only allowed inside a parenthesized argument list" at position (2). I've got the feeling that the error message is not correct. Firstly. The error message directs me to the invocation (parameters) of
doAction
function. But, what is the difference between invocations (1) and (2)? I don't see any. In the IDE, compiler marks the block of
doAction
function, that it is probably here something wrong. Would it be more appropriate that compiler should emit an error message that in this case (this kind of pattern) function block is not allowed? And secondly, if the error were correct, than in my opinion it should not include the term "parenthesized argument list". I was looking for this definition in Kotlin grammar. Regrettably, I found only parenthesizedType, parenthesizedUserType and parenthesizedExpression. Wouldn't in this case be more appropriate that the error message would be related with functionValueParameters? I have tested above code in Kotlin version 1.9.22 and 2.0.0-beta3. Please, show me where my understanding is not correct. In case it is, should I file an issue in https://youtrack.jetbrains.com/? Thank for your answer. Kind regards, Andrey
r
The block marked with (2) is an additional lambda parameter, you are trying to pass to your
doAction
function. And you can't pass lambda this way to a vararg function, even if types were correct (and they are not because a lambda is not a String).
3
Compare this code:
Copy code
fun doAction(vararg items: ()->Unit) {
}

fun main() {
    doAction({}, {}, {}) // correct
    doAction({}, {}) {} // incorrect  
}