Proposal for iterable array in inline functions


#1

Kotlin arrays are not iterable and primitive arrays are not generic.
This is not possible due to java interoperability.

In effect, some library functions have 9 overloads, one for each primitive type and one for Iterable (or Collection). The actual code is often identical.

Without overloads, primitive arrays have to be wrapped with asIterable before they can be passed as arguments. This causes boxing of items and is significantly slower (something like factor 30).

Would it be possible to allow arrays to be passed instead of iterables under certain circumstances?

Conditions could be

  • the method is marked (and used) as inline (this excludes Java calls),
  • the iterable parameter is only used in loop expressions and
  • the generic bounds of the iterable match the array type

Example:

inline fun contains42(list: Iterable<Int>): Boolean {
    for (item in list) if (item == 42) return true
    return false
}

// Don't want to have to write this. It's identical to code above.
// inline fun contains42(list: IntArray): Boolean {
//     for (item in list) if (item == 42) return true
//     return false
// }

val items = IntArray(10000) { Math.random().toRawBits().toInt() }
val current = contains42(items.asIterable())   // boxing is slow
val future = contains42(items)                 // behave as if calling commented code, much faster

#2

I understand the idea but I’m not sure it is really a feature required in Kotlin. Arrays are not used that much except for cases where performance is very important (at least in my experience). Therefor most libraries either implement their functionality using Arrays or Lists/Iterables.
The only place I know with implementation for both arrays and iterables is the standard library which if I am not mistaken uses some sort of code gen to create all the different implementations.

Don’t get me wrong, I would support this feature if it was added to the language. I just think that work on multiplatform, coroutines, serialization and some other features is more important resource wise and I’m not sure this feature would be worth the effort right now.
Also I think this can be achieved with annotation processing in a very limited fashion. I haven’t tried it but if you limit yourself to a certain degree I think this can be achieved ( although I’m not sure if it is better than to just copy the function 10 times as I guess it would be quite hacky)