Victor Moroz
Victor Moroz

Reputation: 9225

Using Stream as a substitute for loop

scala> val s = for(i <- (1 to 10).toStream) yield { println(i); i }
1
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> s.take(8).toList
2
3
4
5
6
7
8
res15: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)

scala> s.take(8).toList
res16: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)

Looks like Scala is storing stream values in memory to optimize access. Which means that Stream can't be used as a substitute for imperative loop as it will allocate memory. Things like (for(i <- (1 to 1000000).toStream, j <- (1 to 1000000).toStream) yield ...).reduceLeft(...) will fail because of memory. Was it wrong idea to use streams this way?

Upvotes: 2

Views: 242

Answers (1)

Rex Kerr
Rex Kerr

Reputation: 167891

You should use Iterator instead of Stream if you want a loop-like collection construct. Stream is specifically for when you want to store past results. If you don't, then, for instance:

scala> Iterator.from(1).map(x => x*x).take(10).sum
res23: Int = 385

Methods continually, iterate, and tabulate are among the more useful ones in this regard (in the Iterator companion object).

Upvotes: 5

Related Questions