Learn Scala 3 Fast: Constructs: for Expressions

As you get better and better at using Scala you’ll find that you won’t use for loops very often, but you will start to use a similar construct: for expressions.

A for expression is similar to a for loop, except that it really is an expression, and returns something of value. You create a for expression by replacing the do keyword with the yield keyword. For example, given this list of integers:

val xs = List(1, 2, 3)

you can create a new list of integers from that list, where each element in the new list is twice the value of the elements in xs like this:

val ys = for x <- xs yield x * 2

If you place that code in the Scala REPL, you’ll see that ys has the type List[Int], and its contents are List(2, 4, 6):

scala> val ys = for x <- xs yield x * 2
val ys: List[Int] = List(2, 4, 6)

You can think of the for/yield expression working like this:

“For every element in the list xs (pronounced “exes”), double each element, and then put that new element in a temporary new list. When you have finished doubling every element, return the entire new list.”

Here’s another example of a for expression, this time using a list of strings:

val names = Seq("luke", "leia")

val capNames = 
    for
        name <- names
    yield
        // put as many lines of code as are necessary
        // for your algorithm
        name.capitalize

After that code runs, capNames contains List("Luke", "Leia"). This is because the for/yield expression works like this:

  • Get the first element from the list ("luke")
  • Capitalize it ("Luke")
  • Add that to the new list
  • Get the next element ("leia")
  • Capitalize it ("Leia")
  • Add that to the new list
  • All elements have been processed, so return the new list, and assign its value to capNames

It really is an expression

I try not to repeat myself too many times, but since we’re just getting into this topic: To be clear, the for/yield combination truly is an expression; it returns a value, the value calculated after the yield keyword. That’s why this is called a “for expression.” In other programming languages you may also see this concept referred to as a “for comprehension.”

Transforming the data type

Before we move on, here’s another example of a for expression:

val xs = List("a", "bb", "ccc")
val ys = for x <- xs yield x.length   // ys: List[Int] = List(1, 2, 3)

As shown in the comment, after the code is run, ys has those contents. So a cool thing about a for expression is that you can use it to create a new type of collection: Here I start with xs as a List[String] and convert that into ys, which is a List[Int].

Exercises

The exercises for this lesson are available here.