Streams in Scala: Part 1

scala-logo-cropedLists and other collections in Scala are great, but I think there is real power in Scala streams. Jason Swartz explains them well in the below paragraphs from Learning Scala: Practical Functional Programming for the JVM:

The Stream type is a lazy collection, generated from one or more starting elements and a recursive function. Elements are added to the collection only when they are accessed for the first time, in constrast to other immutable collections which receive 100% of their contents at instantiation time. The elements that a Stream generates are cached for later retrieval, ensuring that each element is only generated once.

Because there is no set limit, a Stream is also considered an unbounded collection.

The largest advantage is probably that “elements are added to the collection only when they are accessed for the first time.”

Very simple streams can be created like Lists. Try the following statements in the Scala interpreter and you will see these results.

A stream of 1,2,3,4,5:

scala> Stream(1,2,3,4,5)
res9: scala.collection.immutable.Stream[Int] = Stream(1, ?)

A stream of “1 to 10”:

scala> Stream(1 to 10)
res10: scala.collection.immutable.Stream[scala.collection.immutable.Range.Inclusive] = Stream(Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ?)

Using the Stream.cons method, you can create more complex streams. It takes two parameters, the first is a value and the second is another stream.

Here is something you would never do, but it shows how you might use the cons method:

scala> val onetwothree = Stream.cons(1,Stream.cons(2, Stream.cons(3, Stream.empty)))
onetwothree: Stream.Cons[Int] = Stream(1, ?)

scala> onetwothree foreach println
1
2
3

A common way you might usually use Stream.cons is to define a recursive function that calls itself, generating the stream you want. Here we define a stream of square numbers from a squares function. It takes an Int parameter which is the starting point of the stream:


scala> def squares(x: Int): Stream[Int] = {
| Stream.cons(x * x, squares(x + 1))
| }
squares: (x: Int)Stream[Int]

scala> squares(1) take 5 foreach println
1
4
9
16
25

scala> squares(10) take 5 foreach println
100
121
144
169
196

You can use “#::” as an alternate syntax for “Stream.cons” which makes puts your code in a more functional style:


scala> def squares(x: Int): Stream[Int] = {
| (x * x) #:: squares(x + 1)
| }
squares: (x: Int)Stream[Int]

scala> squares(1) take 5 foreach println
1
4
9
16
25

One thought on “Streams in Scala: Part 1

Leave a Reply

Your email address will not be published. Required fields are marked *