In the first two units of this week we have moved from pure functional programming to a combination of functional and imperative programming. Another feature often associated with imperative programming are loops, and these will be studied in this unit. In fact, it turns out that loops, as a feature, are nonessential for comparative languages. With just variables we can already model all imperative programs. So if an imperative program contains a loop, how do you emulate that? Well, you can emulate the loop itself by using a function. Let's see an example. Here's a Scala program that uses the familiar while loop. It's an example that raises x to the power of a exponent, and it uses the usual loop that works with successive multiplications. It's not the best way to express power in Scala. It serves just to as an example to introduce a loop. So in Scala, the while loop is actually a language construct, and while is a keyword, but it turns out that it wouldn't have been necessary. We could have defined while just using a function. To show the difference between the built-in while and the function, we name the function with all capitals, WHILE. So that function WHILE can be defined as you see here. It would be a function that takes a condition and a command, and its result type would be Unit. And what it would do is it would execute the command, as long as the condition was true. So, it would say, if condition holds, then execute command, and do a recursive call to WHILE, with the same condition at the same command. If condition is false, simply return with the unit value. So, one thing to notice that both the condition and the command must be passed by name, so that they can be re-evaluated in each iteration. Otherwise, if the condition was by value and maybe initially true, the while loop would loop forever because the condition would never be re-evaluated to be false. The other observation is that the while loop is tail recursive, so the recursive call happens as the last action in this branch of the if, and that means it can be implemented in constant stack space. Implementing the recursive call back just to jump back to the beginning of the code here, in a way which is just as efficient as a native while. Now, you've seen how to emulate while loops with just a function definition in the call. What about repeat? Let's write a function that implements a repeat loop to be used as follows, REPEAT, command, and then it should stop once the condition here is true. How would you do that? If we look at the usage of the repeat function, then it's clear that the definition will, should look like this. REPEAT takes a by name parameter command of type arrow Unit and a by named condition of type arrow Boolean, so it's also a by name parameter. And its body would be like this. So repeat, we said, should always execute command first. And then if the condition is true, it should stop. And otherwise it should do a recursive call with the same command and the same condition. Now, here's a variation of the previous exercise. Let's say I'm not happy with the previous syntax of repeat, and I want to write something like this instead, REPEAT, command, UNTIL, condition. Can you devise a definition of a repeat function that would support that call syntax? That's actually feasible, even though it's quite a bit harder than what we've shown in the previous example, so it's left as an optional exercise for you. It's not essential to follow any of the rest of the course, but if you want to have some fun playing with the capabilities of Scala syntax, then it should be quite instructive. Now, we've seen two variants of a hypothetical repeat loop. what I haven't told you yet is what syntax Scala actually uses. Turns out neither of the two. What Scala actually uses is the same, again, as in C or in Java. You write do and then some command. And then you'd write while and then a condition. So we've seen while loops and repeat loops and do loops, the last category of loops that we should cover is for loops. Here it turns out that the classical for loop that you'll find in C or C++ or Java, cannot be modeled simply by a higher order function. So if you look at such a for loop, you see the example here, you see that there's actually a definition here, that i equals one, that introduces a variable that is used later on in the other parts of the for loop. And that's something that cannot be straightforwardly achieved by using just higher order function applications. And, as a matter of fact, Scala does not have this kind of for loop. What it has is a kind of for loop that is similar to Java's extended for loop, so you would write something that's equivalent to the example up here like this, for i ranging over one until three, system out.print i plus space. And that would display one and two. Now, this looks pretty much like a for expression, like the ones you've seen in the functional programming course and also in the first week of this course, and in fact that's no accident. For loops translate quite similarly to for expressions, but where for expressions translate into combinations of functions map and flatMaps, for loops translate into combinations of the function foreach. So, foreach is a function that's defined on all collections with elements of type T. It would take an argument which is a function from T to Unit, give you back a Unit. And its effect would be to apply the given function argument f to each element of the collection. So, here's an example where you use two nested generators. You let i range from one until three, j range over the elements of the string abc, and you print i plus space plus j. So in this case, that should print 1a, 1b, 1c, 2a, 2b, 2c. That expression gets expanded into two nested calls of foreach. You start with the first range, one one until three. You apply the closure, i arrow something, to that range. That closure takes each element i, taken from one until three, and there's a nested call of foreach, where the base collection is the string abc. The loop variable is the j, and the final result is the println. So to summarize, we have seen the different forms of loops that you would expect in imperative languages. And have shown how each of these can, at least in principle, be translated into more basic units in the Scala language. While and repeat can be translated into simpler cause of higher functions, and the extended for loop gets translated into inter-combinations of the foreach method, which is defined on every Scala collection.