Arrays-2.0, multiple varargs and collection literals


some things are described bad due to my language limitations and some because I was trying to make proposal as simple as possible.
So, need to clarify: vararg arrays are always passed as values and always created and declared explicitly.
Here is example of behavior in case with array of Any you described:

fun takesVarargArrays(a: vararg [Any], b: vararg [Any]) 
    = println("a.size=${a.size}, b.size=${b.size}")

takesVarargArrays([[]], [])     // a.size=1, b.size=0

On JVM when you passes whole array to varargs of Any you wraps array in array and passes it to function - here it’s visible.
Outer array is vararg array used in function. Inner is an content of vararg array.
Everything is straightforward.

If we go deeper, we can even get rid of * and vararg operators (that are just syntax sugar for arrays).
I.e. Rust language don’t have varargs and I really like this decision
because that same functionality can be achieved with following syntax:

fun takesArray(a: [Int] = []) 
    = println("a.size=${a.size}")

takesArray()                    // a.size=0
takesArray([])                  // a.size=0
takesArray([1] + [1, 2])        // a.size=3
val array = [1, 2]
takesArray(array)               // a.size=2
val value = 1
takesArray(array + [1, value])  // a.size=4

that don’t introduces additional complexity to parser and not confuses novices with extra operators.
As you see, spreading multiple arrays can be easily replaced with array concatenation.

Problem is only that currently Kotlin creates defensive copy of array with *, and I’m not sure if it’s safe to not create it.

About last argument convention: it makes syntax even simpler:

takesArray [ 1, 2, 3 ]

and it’s not ambiguous (see step 6. sorry if it was unclear before edit).
It should simplify collection creation and building complex objects.

As for collection factory functions, you will be able to use them in this way:

listOf [1, 2, 3]
mutableListOf [1, 2, 3]
mapOf [
    1 to 2,
    2 to 3]

But they don’t look like collection literals (on top of Kotlin feature survey).
I propose to deprecate these functions and construct collections like these:

List [1, 2, 3]
MutableList [1, 2, 3]
Map [
    1 to 2,
    2 to 3]

Don’t sure it will be implemented as constructors or uppercase functions…
But same collection types remain and immutablility will be on first place (confusing example in 5 also updated).

I’m really didn’t know about multiple arrays spreading and missed case of [Any],
good catch!

1 Like