Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected behaviour of iterator on String

Can anyone explain why these iterators behave differently? I generally expect a String to act like an IndexedSeq[Char]. Is this documented anywhere?

val si: Iterator[Char] = "uvwxyz".iterator
val vi: Iterator[Char] = "uvwxyz".toIndexedSeq.iterator

val sr = for (i <- 1 to 3) 
           yield si take 2 mkString
  //sr: scala.collection.immutable.IndexedSeq[String] = Vector(uv, uv, uv)

val vr = for (i <- 1 to 3) 
           yield vi take 2 mkString
  //vr: scala.collection.immutable.IndexedSeq[String] = Vector(uv, wx, yz)
like image 556
Luigi Plinge Avatar asked Nov 28 '11 23:11

Luigi Plinge


1 Answers

There are no guarantees about the state of the iterator after you invoke take on it.

The problem with iterators is that many useful operations can only be implemented by causing side effects. All these operations have a specified direct effect but may also have side effects that cannot be specified (or would complicate the implementation).

In the case of take there are implementations that clone the internal state of the iterator and others that advance the iterator. If you want to guarantee the absence of side-effects you will have to use immutable data structures, in any other case your code should only rely on direct effects.

like image 91
Moritz Avatar answered Oct 11 '22 22:10

Moritz