In this session, we're going to look at a core concept of imperative programming, namely loops. In fact, our proposition is that variables are enough to model all imperative programs. What about control statements such as loops? In fact, we can model them just using functions. For instance, here's a Scala program that uses a while loop. It's the imperative computation of the power function, takes a double and then exponent and then you have a loop that while the exponent is greater than zero, you multiply the value r here with x and decrement i by 1 and finally you return r. In Scala, while-do is a built-in construct, but we could define it also using a function. Let's call it whileDo. How would that work? Here's how we could define that function. We have whileDo, it would take a condition and a command. Here's an example application of whileDo. We would write whileDo x greater or zero. Y equals y times y equals x minus 1. Assuming we have 2 variables, y and x defined. What that translates to is a function called, for a whileDo, with the first argument, x greater than zero, and the second argument, which is the body that you see here. These are just plain function arguments. They can be written in parents or in basis. It doesn't make a difference. So to make this call syntax work, we need a definition of whileDo with 2 parameters sections. The first is type Boolean and the second is type unit, which is essentially the uninteresting type that only has the single value, open parents, closed parents. The result return type of the whileDo is also unit. It's important to note that both the condition of the command are by name parameters because the actual arguments will need to be reevaluated multiple times as we go through the loop. The value of the while then is as follows. If the condition holds, then execute the command and recursively call whileDo with the same condition and the same command. Otherwise, terminate, that means return the unit value as a result. Quick check is whileDo tail recursive. The answer is yes. It calls itself only as its last action here. So that means whileDo can operate with constant stack size just like a native while loop. Here's an exercise for you. Write a function implementing a repeat loop that is used as follows: repeatUntil then a command and then a condition. It should execute command one or more times until a condition is true. Let's look at the worksheet. We need to implement this function here. It will execute command at least once. Let's do that and get it out of the way. Then we say if the condition is true we finish, but if the condition is not true, then we will do another iteration through the loop. Else, we will return the unit value. We get an error here. It says overloaded or recursive method repeatUntil needs return type. Yes, that's a limitation of Scala's type inference, that as soon as a method is recursive, it needs a return type. In this case it's just unit. As a simplification., if you have an if-then-else returning unit value of type unit, then you can leave out this else unit value. This would work just as well. Let's put it to the test. I have here this little program involving variables x and y and we go through the loop until x is 5, doubling y at each iteration. What we get are the initial values and the final value for y is 64 as expected. Here's another exercise which is optional and more open-ended. Is it also possible to obtain the following syntax which would look more like a repeatUntil in a traditional language? We want to write repeat and then a command. Then we want to write until like this and the condition should follow the until. Can we write the Scala definitions that support that calling syntax? To find the solution, let's analyze what these two sugars do. It would be repeat of the command, in parents or not or basis, it doesn't matter and then it would come down to a method called until which gets the condition as additional argument. That means we are after a repeat function that returns something that has an Until method. You see a possible solution in the worksheet. I define a repeat method which takes a by-name parameter body, and it creates an object of class Until passing it the same body. Until takes body as a by-name parameter again and it has an until method, lowercase now, which takes another condition also by name. Its body then would say, "Well, if the condition doesn't hold, then I go once more around the body." So execute body and recursively call Until with the same condition. That would be a solution. In future Scala versions, to be able to write this without a warning, I should declare Until infix because otherwise, it would insist on a dot in front, and to keep this sort of more traditional command syntax, I don't want that. That's why we have an infix annotation in front of the Until at the worksheet. We've seen that we can do while loops and repeat loops credibly using just functions in Scala. What about the classical for loop of C or Java? The classical for loop cannot be modeled simply by a higher-order function. The reason is that in a Java program like this one, the argument of for contain a declaration, this one here. That's a new declaration of i, defines a new i inside an argument, which then is visible in the other arguments and in the body. That wouldn't work because whatever we write as actual arguments for a function in Scala would stay there. Anything we define here, its scope would just be the first argument here and the remainder wouldn't see the thing we define here. However, in Scala, there is a kind of for loop similar to Java's extended for loop. What we can write is for i taken from 1 to 3, do System.out.print, and then the value of i. For loop like this is very similar to a for expression that you have seen already. Except that where we have yield in a for-expression, we have do in a for loop. Like for-expressions, for loops also translate into combinations of higher-order functions but instead of a map and flat-map, they translate into the function foreach. Foreach is defined on collections with elements of type T as you see here. So foreach takes a function that maps T to unit and returns unit and what it does is it applies the given function to each element of the collection. For instance, this for expression for i taken from 1 until 3, j taken from the string abc, do print on i and then g. That would translate to 1 until 3, the range dot foreach i, abc, the string dot for each j and then print on the body that we have seen up here.