# Sequence Comprehensions

Scala offers a lightweight notation for expressing sequence comprehensions. Comprehensions have the form `for (enumerators) yield e`, where `enumerators` refers to a semicolon-separated list of enumerators. An enumerator is either a generator which introduces new variables, or it is a filter. A comprehension evaluates the body `e` for each binding generated by the enumerators and returns a sequence of these values.

Here is an example:

``````object ComprehensionTest1 extends App {
def even(from: Int, to: Int): List[Int] =
for (i <- List.range(from, to) if i % 2 == 0) yield i
Console.println(even(0, 20))
}
``````

The for-expression in function introduces a new variable `i` of type `Int` which is subsequently bound to all values of the list `List(from, from + 1, ..., to - 1)`. The guard `if i % 2 == 0` filters out all odd numbers so that the body (which only consists of the expression i) is only evaluated for even numbers. Consequently, the whole for-expression returns a list of even numbers.

The program yields the following output:

``````List(0, 2, 4, 6, 8, 10, 12, 14, 16, 18)
``````

Here is a more complicated example which computes all pairs of numbers between `0` and `n-1` whose sum is equal to a given value `v`:

``````object ComprehensionTest2 extends App {
def foo(n: Int, v: Int) =
for (i <- 0 until n;
j <- i until n if i + j == v) yield
(i, j);
foo(20, 32) foreach {
case (i, j) =>
println(s"(\$i, \$j)")
}
}
``````

This example shows that comprehensions are not restricted to lists. The previous program uses iterators instead. Every datatype that supports the operations `withFilter`, `map`, and `flatMap` (with the proper types) can be used in sequence comprehensions.

Here’s the output of the program:

``````(13, 19)
(14, 18)
(15, 17)
(16, 16)
``````

There is also a special form of sequence comprehension which returns `Unit`. Here the bindings that are created from the list of generators and filters are used to perform side-effects. The programmer has to omit the keyword `yield` to make use of such a sequence comprehension. Here’s a program which is equivalent to the previous one but uses the special for comprehension returning `Unit`:

``````object ComprehensionTest3 extends App {
for (i <- Iterator.range(0, 20);
j <- Iterator.range(i, 20) if i + j == 32)
println(s"(\$i, \$j)")
}
``````