You are using .toStream()
which means that the whole collection is lazy. Without it, your output would be first a hundred "doing"s followed by numbers from 1 to 100. However, Stream
evaluates only the first element, which gives the "doing 1" output, which is where it stops. Next element will be evaluated when needed.
Now, I couldn't find any details on this in the docs, but I presume that runForeach
has an implementation that takes the next element before invoking the function on the current one. So before calling println
on element n, it first examines element n+1 (e.g. checks if it exists), which results in "doing n+1" message. Then it performs your println
function on current element which results in message "n" .
Do you really need to map()
before you runForeach
? I mean, do you need two travelsals through the data? I know I'm probably stating the obvious, but if you just process your data in one go like this:
val rx = Source((1 to 100).toStream)
rx.runForeach({ t =>
Thread.sleep(1000)
println(s"doing $t")
// do something with 't', which is now equal to what "doing" says
})
then you don't have a problem of what's evaluated when.