MattHicks.com

Programming on the Edge

Loops in Scala

Published by Matt Hicks under , , , on Thursday, October 01, 2009
Lately I've been learning the ins and outs of the Scala language and I have to say, having programmed in Java for the past several years, that Scala is scratching where I itch. It is a lot to grasp and mind opening, but all-in-all I see Scala as what Java could have evolved to if they would have just been willing to ditch some backwards compatibility and fix some stuff rather than just adding more and more work-arounds.

Anyway, that's not the point of this post. I wanted to post some cool loop examples I've been playing with in Scala.

In Java we have the standard incrementing for-loop:
for (int i = 0; i < 10; i++) {
...
}

In Scala we have something similar, but I believe more elegant:
for (i <- 0 until 10) {
...
}

However, with Java 1.5 we got the enhanced for-loop when we don't care about indexes:
for (String s : listOfStrings) {
...
}

In Scala we do something similar, but with a more consistent syntax:
for (s <- listOfStrings) {
...
}

Or, we can go a step further with Scala since it's a functional language we can get rid of the for loop entirely and use a friendly method available to us called "foreach" and pass each entry to another method:
listOfStrings.foreach(doSomething);

def doSomething(s:String):Unit = {
...
}

To me this is of significant appeal because we don't end up with a bunch of embedded for-loop blocks in our methods we focus more on modular functionality to deal with the results of the iteration instead.

7 comments:

Anonymous said... @ December 3, 2010 at 3:44 AM

What happens if your incrementor e.g. is not i++ what happens if I wish to count up for example i+=2 OR I+= #some other integer

Matt Hicks said... @ December 3, 2010 at 10:21 AM

Simply modify the call to Range to step by 2:

for (i <- 0 until 10 by 2) {
...
}

John Lonergan said... @ December 23, 2011 at 5:49 PM

Re performance.

Comparing performance I see unexpected results - any comments on the following.

Counting up with Int
for ( i:Int <- 0 to 500000000) { }
took 859ms

Counting up with Long is massively slower ..
for ( i: Long <- 0L to 500000000L) {}
took 5000ms

Counting down is much faster and about same timing with int or long

for ( i:Int <- 500000000 to 0 ) {}
took 341ms

for ( i:Long <- 500000000L to 0L ) {}
took 343ms


CPU : Core i5 M520

Matt Hicks said... @ December 24, 2011 at 6:34 AM

@John, that's interesting. I'll have to play around with that and see what's going on. Have you tried decompiling the code into Java and seeing what the code looks like and how it differs? That's what I would probably do to get a better idea of what the Scala compiler is doing behind the scenes.

Arjuns Gab said... @ June 7, 2012 at 11:12 PM

How do I do:
float f;
for(f=2.0; f<=20.0; f+0.25) {
...
}

I dont see any room for the increment specially for float/double types ?

Matt Hicks said... @ June 8, 2012 at 3:22 PM

@Arjuns, it's actually quite elegant:

for (f <- 2.0 to 20.0 by 0.25) {
...
}

Unknown said... @ June 29, 2012 at 4:15 PM

@John:

You should have done:
for (i: Long <- 500000000L to 0L by -1) {}

instead of:
for (i: Long <- 500000000L to 0L) {}

Latter doesn't do anything because 500000000L is greater than 0L.

for (i: Long <- 0L to 500000000L) {}
took 5000ms

for (i: Long <- 500000000L to 0L by -1) {}
took 7000ms when benchmarked

So counting down seems to be much slower than counting up

Post a Comment