Is there a good reason for it? Does it allow some optimizations in some contexts?
Because it’s a bit problematic when you’d like to copy the contents of the iterator into several places, for example to an UnrolledBuffer
. Currently we must call splitAt
on the iterator for every segment we want to handle separately, and even only if we want to know if we have exhausted the iterator.
Disclaimer: this is only an incomplete answer, as it doesn’t address your specific use-case with UnrolledBuffer
.
I believe that iterators are not meant to be used more than once. They are not collections, but can represent the state of an iteration.
As such, trying to use an iterator more than once indicates a conceptual coding error. However, elements of an iterator can be collected into a collection, and the latter can be reused.
Because consuming the Iterator may have altered state, made network calls, read files, etc.
They are intended to be consumed once, and only once.
If you want to copy is contents to multiple outputs you have a couple of options:
- Use
foreach
- Load it all in memory on a strict collection like
Vector
- Use a
view
which will re-run its logic every time (be careful about the implications of this).
You may also consider more powerful abstractions like fs2 or AkkaStreams.
Something similar just happened in an unrelated API, with Java’s CompletableFuture
, where minimalStage
gives you a restricted CompletionStage
which is a CompletableFuture
that doesn’t let you test if it has completed.
That is, the API seems to take away functionality in favor of frustration.
Per the other topic, grouped
actually distributes ArraySeq
, so if you wanted equally sized slices, that is just using copyToArray
.
TIL:
scala> res10.asInstanceOf[collection.immutable.ArraySeq[Int]].unsafeArray
val res12: Array[_] = Array(1, 2, 3)
If that is not exactly what you want, you can roll your own. I know if this discussion continues for a bit, Ichoran will chime in to say he needs this on occasion and has one in his library.