Idea: kotlin.collections.repeat function


#1

See this question on SO.

What’s the ‘best’ (i.e. most efficient / shortest / easiest) way to infinitely repeat a collection or array? Currently, no repeat(): Sequence<T> or repeat(times: Int): Sequence<T> functions exist for these classes. I think they could be handy additions to the standard library!

Currently, without the experimental coroutines, the easiest method I think is:

val collectionOrArray = ... // whatever collection, indexable with [i]
var i = 0
val infiniteSequence = generateSequence { collectionOrArray[i++ % collectionOrArray.size] }

However, this is not easy to read (especially due to the modulo). What do you think? I think it would be much easier to just use collectionOrArray.repeat().


#2

If you have any infinite sequence, you can use it to make cycling sequence from the given collection:

val infiniteSequence = generateSequence(0) { it + 1 }.map { collection }.flatten()

#3

Don’t you think that’s quite complicated, or at least relatively verbose, to work out for someone looking for such functionality?


#4

I am not sure, what do you really propose. You want this feature to be included in the standard library? It is to narrow for that. You can always define a global extension function:

fun <T> Collection<T>.repeat(): Sequence<T> {
  return generateSequence(0) { it + 1 }.map { this }.flatten()
}

That is the power of kotlin for you.


#5

Clojure has a similar function in their standard library: https://clojuredocs.org/clojure.core/repeat, so I don’t think it’s unreasonable for a functional language to have.


#6

Haskell has it too in its standard library (called Prelude), which is the reason that I know of it. I’ve used it a lot in Haskell and now I found use for it in Kotlin too. I know an extension function can help me here, but a standard library function might be helpful for others too.

Therefore, I propose the repeat function is added to the standard library for all/most kotlin.collections supertypes.

What are next steps I can take to include this function in Kotlin? Is this post enough for the Kotlin devs to internally consider its value? Should I open an issue somewhere? Should I just implement it myself and open a PR on GitHub?

In general, Haskell has some nice and simple functional building blocks for functional programing, some of which are already found in Kotlin, but others may be worth considering for Kotlin too. Haskell’s repeat :: a -> [a] is one example.


#7

@erik You said you had used it a lot, could you describe several concrete cases where it comes handy?


#8

After looking at some old Haskell projects, the main use of repeat for me was to generate streams of repeating data as a source for unknown (remote) listeners, but no other uses for me. I was under the impression I had used it a lot more. Nonetheless, repeating any object to form an infinite sequence is a quite elementary functional operation.

I agree that if there’s no use case, then why support by default? However, if others can think of uses for a repeat function for Kotlin, please let us know.

Also note that Haskell’s repeat equivalent using Kotlin’s Sequence is

generateSequence { someIterable }

However, I originally wanted to put the contents of someIterable in an infinite sequence, so:

generateSequence { someIterable }.flatten()

My bad, sorry! This is equivalent to Haskell’s cycle :: [a] -> [a] function.

Because these two sequence generators are quite compact and easy to understand (I thought of this syntax just now), I think no stdlib repeat is required, but would still be nice.