Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - iterators and takeWhile

Tags:

iterator

scala

I am running the following piece of code:

 val it = List(1,1,1,2,2,3,3).iterator.buffered
 val compare = it.head
it.takeWhile(_ == compare).toList

and it returns (1,1,1). However, if I run this as:

val it = List(1,1,1,2,2,3,3).iterator.buffered
it.takeWhile(_ == it.head).toList

I am getting (1,1). Why is this the case? Isn't head evaluated upon calling takeWhile and the result should be the same?

like image 830
Bober02 Avatar asked May 03 '13 10:05

Bober02


1 Answers

Because the iterator is mutable, the value of it.head depends on when it is evaluated.

Inspecting the implementation of takeWhile reveals that it removes the head of the iterator before applying the predicate.

So, on the third iteration, it.head evaluated from within the predicate will be 2, because the third element has already been removed.

This is an illustration of why you should prefer immutability. It rules out a whole class of non-obvious behaviour like this.

like image 112
Ben James Avatar answered Sep 28 '22 19:09

Ben James