The following code prints “*1”. What’s mystifying is if I remove the comment it returns “*4” which is what I was expecting
var max = 0
lazy val list: Stream[Int] = 1 #:: Stream.from(2)
list.takeWhile {
x =>
max = x
x < 4
}//.foreach(println)
println("*" + max)
First of all: the
lazyin your second line isn’t doing anything—you can remove it and get the same result.More importantly:
takeWhileis actually lazy, in that it just returns anotherStream, and nothing past the head of that stream will be evaluated until it’s needed. Consider the following:You and I know that
sis going to be an infinite stream, but if we fire up the REPL and type this in, it’s perfectly happy to evaluate it:The same thing is happening in your example: the
(Int) ⇒ Booleanthat you’ve passed totakeWhileisn’t going to get fed any elements beyond the head of the stream, until something like yourforeachmakes that necessary.You can see this even more dramatically by adding something like a
printlninside of thetakeWhilepredicate:Clearly the predicate only gets called for the head of the stream, until we force the evaluation of the rest of the stream by calling
toList.