Ever Used Scala Views For Lazy Transformation?

Reading Time: 3 minutes

We all know the power of lazy variables in Scala programming. If you are developing the application with huge data then you must have worked with the Scala collections. Some mostly used collections are List, Seq, Vector, etc. Similarly, you must be aware of the power of Streams. The streams are a very powerful tool for handling the infinite flow of data and streams are powerful because of there lazy transformations. As we know most of the Scala collections are strict so applying an operation on immutable collections creates a new collection. The size of the collection can be huge in the big data world. So, what if you have to apply a lot of transformations to the collection? Is there a way to handle collections in a lazy way? What if you can find a way to apply operations on your usual collections lazily? In this blog, we will be talking about the Scala views and how to use them.

Image result for scala lazy collections

Convert a strict collection to a non-strict collection with views:

The Scala collections have many methods that can construct new collections like map, filter, and flatMap. These methods are called transformers because they take one collection and generates new collections by making changes.  

There are two general ways to create transformers:

  1. Strict: A new collection is created with all the elements of its collection as a result of transformation.
  2. Lazy (Non-Strict): It constructs a proxy for the result collection, and the actual elements get created on-demand when required.

An example of a non-strict transformer is as follows:

def addTwo: Int => Double = _ + 2
 //OP: addTwo: addTwo[] => Int => Double

def lazyMap[T, U](coll: Iterable[T], f: T => U) = new Iterable[U] {
 def iterator = coll.iterator map f
 }

//OP: lazyMap: lazyMap[T,U](val coll: Iterable[T],val f: T => U) => Iterable[U]

lazyMap[Int, Double](List(1,2,3,4), addTwo)

//OP: res0: Iterable[Double] = A(3.0, 4.0, 5.0, 6.0)

What is a view?

In the above example instead of creating a concrete collection, lazyMap only creates a new iterable without stepping through the elements and the function f is applied to the elements when they are demanded.

In terms of Scala, by default collections are strict in all of the transformers, except for streams.  Unlike other collections, Streams implement all the transformers lazily. Despite that, there is a way to convert a strict collection into a lazy one and vice-versa using views.

“A view is a special kind of collection, which represents a base collection, but implements all the transformer functions lazily.”

How to create views?

The process of creating a view from a collection is very simple and you can use the view method of a collection.

Ex.

val list = List(1,2,3,4)

val listView = list.view

val listWithAddTwoAndOne = listView.map(_ + 2).map(_ + 1)

listWithAddTwoAndOne.force


In the above example, the list is a strict collection of integers. Using list.view we can find a view of this collection which is another collection with all transformers defined lazily. Using listView.map(_ + 2).map(_ + 1) we are applying two transformations on the view. Unlike strict collections, after applying the transformation it does not generate a new collection because of lazy transformers. That means the transformations are not really applied to the collection yet and we get a scala.collection.SeqView[Int,Seq[_]] from this line. The actual transformations are applied to the collections when we apply the force method to view. Now both the transformations are applied at once on the collection. In this way, there is no overhead of creating multiple collections after each transformation.
OP:

Points to be noted here are:

  • To use a view of a collection, you can use the view method of the collection. In the above example, the list is a collection, and list.view is the same collection, but with all lazy transformers.
  • To get a strict collection back from the view, you can use the force method on the view.

Few more important points to remember are:

– Either you apply views in the purely functional code where collection transformations do not have side effects.

– Or you apply them over mutable collections where all modifications are done explicitly.

– What’s best avoided is a mixture of views and operations that create new collections while also having side effects.

I hope you enjoyed the post. To find more interesting blogs about Scala programming language, please visit this link.

Thanks!

Knoldus-blog-footer-image

Written by 

Girish is a Software Consultant, with experience of more than 3.5 years. He is a scala developer and very passionate about his interest towards Scala Eco-system. He has also done many projects in different languages like Java and Asp.net. He can work in both supervised and unsupervised environment and have a craze for computers whether working or not, he is almost always in front of his laptop's screen. His hobbies include reading books and listening to music. He is self motivated, dedicated and focused towards his work. He believes in developing quality products. He wants to work on different projects and different domains. He is curious to gain knowledge of different domains and try to provide solutions that can utilize resources and improve performance. His personal interests include reading books, video games, cricket and social networking. He has done Masters in Computer Applications from Lal Bahadur Shastri Institute of Management, New Delhi.

Knoldus Pune Careers - Hiring Freshers

Get a head start on your career at Knoldus. Join us!