Scala Tutorials Part #13 - Loops


Loops

Loops are fundamental building blocks of imperative programming languages. Since scala also supports imperative style, lets take a look at different variations of loops and how they work.

This is part 13 of the scala tutorial series. Check here for the full series.

While loops in scala are very similar to their other language counterparts, so I am not going to explain it. The for loop however, can be used as a drop in replacement for any while loop construct.

Index

Concept of looping

The concept of looping came up in early languages such as the assembly language. Several variations exist with different instruction sets.

Taken from here, a few examples below in several languages.

For loops in assembly

        xor cx,cx   ; cx-register is the counter, set to 0
loop1   nop         ; Whatever you wanna do goes here, should not change cx
        inc cx      ; Increment
        cmp cx,3    ; Compare cx to the limit
        jle loop1   ; Loop while less or equal

Do while in C

int x=1;
do{
    //Do something!
    //Increment the counter so that you avoid infinite loops
    x++;
    
}
while(x<10)

The concept is the same immaterial of the language i.e doing something repetitively.

Introduction to the Syntax

Loops in Scala do not have a three part structure like Java. A typical for loop in Java would like below,

for(int i=0;i<10;i++){
//Some code
}

A typical Scala for loop on the other hand does not have the increment part and also the variable declaration is slightly different.

for(i <- 1 to 10){
    println(i)
}

Scala does not really have anything that is similar to Java for loops. If you take a closer look, the to is actually a method on the RictInt class which gives back a Range collection from 1 to 10. But notice that we are using these directly from the Int class. This is because the class RichInt is not a normal class but something called a booster class. We will take a look at booster classes in later tutorials. For now, it is sufficient to understand that the for is not something native to Scala, but it is just syntactic sugar over iterating a Range.

The i <- 1 to 10 part is called a loop generator. In below sections we will see how we can combine multiple generators to create a nested for loop.

Controlling both indexes

In any for loop, there are two indexes involved i.e the beginning index and the ending one. We can use different constructs if we want to control either of these indexes.

val array = Array(10,12,23,44)

for(i<-0 to array.length-1){
    println(array(i))
  }
  

Starting from i = 0 we loop till array length -1. As in many languages, arrays are indexed from 0. In this style of writing, we need to be careful in both the beginning and end index. Typically one would make mistakes by starting at index 0 and then ending at array.length which would cause ArrayIndexOutOfBoundsException.

Controlling only the starting index

If we are worried about only the starting index then scala has a special construct for that.

for(i<-0 until array.length) {
    println(array(i))
}
  

The until keyword makes sure that the loop iterates until the last element without us having to deal with the end index. Similar to to, until is also a method in the RichInt class.

No Index for expressions

In java there are Iterators in which you can loop through arrays without worrying about indexes and there are for loops in which we need not worry about the indexes.

 
 int a[] = {10,12,23,44};

 for(int i:a){
  System.out.println(i);
 }

The scala version of the above would be quite similar,

for(i<- array) {
    println(i)
}
  

There are reasons about why one would use any of the above. In the no index version there is no control over where the element is in the array i.e there is no track of the index. In certain situations there is no need to worry about it.

For loop with guards

Many times we want to loop over something that satisfies a condition. In java we typically do so by wrapping the for loop inside of an if statement. In scala there is a special syntax for it and they are named as Guards in loops. Let’s look at an example.

 for(i<-0 to 30)
      if (i>10 && i<30) {
    println(i)
  }

Notice that the if condition is wrapped inside of the for construct. We can also chain complex if conditions.

for(i<-0 to 30)
      if (i>10 && i<30)
      if (i%2 == 0)
      if (i%4 == 0)
      {
    println(i)
  }
  

This is just syntactic sugar over normal if statements.

Yield construct

For loops unlike Java generates a value in Scala. We saw this already in part 7 where is every expression is a value and every value is an object in Scala.

Scala loop value

The variable x is of type Unit which is the equivalent of void in java, but as discussed before, this is actually a type. Scala has a new keyword called yield which produces new value out of a for loop.

val a = Array(1,2,3,4,5)

val b = for (i <- a) yield i*2

Unlike regular for loops which is of type Unit this actually yields as the name implies another array of 5 elements. We can even print out the array b which will turn out to be numbers 2,4,6,8,10. As we get deeper into functional programming, we will find out that this way of looping leads to really good and maintainable code.

Multiple Generators

We can easily create nested for loops with generator syntax.

for(i <- 1 to 5;j <- 1 to 5){
    println(s"i: $i j:$j")
}

This prints out

i: 1 j:1
i: 1 j:2
...
i: 5 j:5

There are more advanced constructs possible with loops, but this should be enough to get started. As we explore more into Scala, we would find that loops can be replaced with more powerful constructs which are thread safe and safer/elegant to work with.


Tagged Under


Scala


Search this website...




Keeping up with blogs...

I blog occasionally and mostly write about Software engineering and the likes. If you are interested in keeping up with new blog posts, you should follow me on twitter where I usually tweet when I publish them. You can also use the RSS feed , or even subscribe via email below.

Feedio Subscribe


Share & Like

If you like this post, then you can either share/discuss/vote up on the below sites.



Thoughts ...

Please feel free to share your comments below for discussion

Blog comments powered by Disqus