I noticed that Kotlin zip only really operates on ...
# announcements
n
I noticed that Kotlin zip only really operates on two sequences, compared to say python's zip which conveniently works on more than 2. How would you zip multiple sequences without nesting the result deeper and deeper? This sort of thing makes me scratch my head a bit on why tuples were removed from the language.
b
Can't you just use Pair instead of tuples?
n
well, if you have 3 sequences, or 4
and you zip them together
and you want to use pairs
you'll keep nesting
which is kinda lame, no
like in python you can write something like,
for a, b, c in zip(seq1, seq2, seq3)
in kotlin you'd have something more like `for (val ((a, b), c) : seq1 zip seq2 zip seq3) maybe
and as you add a fourth sequence, you keep nesting
for (((a, b), c), d) ...
m
right, kotlin doesn't support tuples, if I remember correctly it's because it wouldn't work with the JVM
best thing you could do is list of lists
something like this:
Copy code
fun main() {
    val list1 = listOf(1,2,3)
    val list2 = listOf(1,2,3)
    val list3 = listOf(1,2,3)
    val list4 = listOf(1,2,3)

    val listOlists = zipLists(list1, list2, list3, list4)
   
  	listOlists.forEach{println(it)}
 
}


fun <T> zipLists(vararg lists: List<T>): List<List<T?>> {
    val maxSize = lists.map { it.size }.max() ?: 0
    val result = List(maxSize) { MutableList<T?>(lists.size) { null } }
    for (row in 0 until maxSize ) {
        for (col in lists.indices)
            result[row][col] = lists[col].getOrNull(row)
    }
    return result
}
output would give you
Copy code
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
n
I think kotlin used to have tuples, they were removed in favor of dataclasses
the issue with your zipLists is that it aassumes that the T is the same
m
yep, that is a limitation
n
that's not even usually true when dealing with zip
Right
m
you could of course use "Any"
n
Yeah, then you throw away type safety, not great.
m
but then there isn't much you could do with the zipped lists
n
i've noticed this is a common thing in Kotlin, abstractions work well for 1, or sometimes 2 objects, but scale poorly.
Another example is
.use
or mutex locking
m
you mean nesting
.use
? haven't found myself doing that much
n
it doesn't happen constantly but when it happens it's kinda annoying
a common example I use often now in python is spawning a supbrocess, and collecting stdout in one file, stderr in another
But, yeah, I mean if something doesn't come up too often, and when it does come up it's usually the same, then you can just write an abstraction for that specific case
And use a dataclass to make it look nice and such
the combination of multiple objects + generic is kinda rough for kotlin
m
yeah it can get ugly but usually I end up rethinking things and taking a different approach
n
yeah, I mean it basically just means you need to do more work at the call site or in your utility code, your generic utilities like zip don't cover as many cases as cleanly. It's not the end of the world.
m
pretty much
n
You would think though, given destructuring syntax, it would have been worth keeping tuples, which would just be generic dataclasses
data class <T, X, Y> Tuple3(val first: T, ....)
m
like automatic compile time created data classes?
n
not like, just exactly data classes
I'm not even suggesting a new language feature, just keeping "tuples" in the standard library
Then you can write overloads for zip
the zip overload taking 2 sequences would give you a sequence of Tuple2's, the zip overload taking 3 sequences would give you a sequence of Tuple3's, etc
m
right
n
and then the user could still give things nice names
m
so basically have the compiler create the data class for you with the specific types based on arguments of whatever you're doing
such as return(data1, data2, data3, data4) creates the data class with the 4 data types
n
something like this
s
Yeah…. it would’ve been nice if Kotlin supported heterogenous lists or tuples to large arity…. Maybe the Arrow FP library can help you out. they have the type
HList
and products: https://arrow-kt.io/docs/0.10/generic/product/ https://arrow-kt.io/docs/0.10/apidocs/arrow-generic/arrow.generic/-h-list/index.html
n
Thanks!
Yeah, it would be nice, my point is just though that even hardcoding dataclasses in this way can get you reasonable mileage, and kotlin i think used to have this and got rid of it
the reasoning was that dataclasses are clearer. but as the example shows, when you are encouraged to use destructuring
it doesn't really matter
the other thing that's brutal in these examples is the Iterable/Sequence divide 😞
It sucks there isn't a concept that encompasses both