In this session, we are going to apply what we learned so far in a larger example. The task is to develop a square root function using Newton's method. That's the first time that we need more than a couple of lines to actually express a program and we will learn new techniques and new tools for doing so. So, what that means is that we want to define a function with the signature. It takes a double and gives me back a double, and return the value is the square root of its parameter x. The classical way to compute that is by successive approximations using the method of Isaac Newton. So, let's see what this method is. To compute square root of x, we start with an initial estimate value. It doesn't really matter what that estimate is as long as it's positive. So, let's pick y = one. And then, we repeatedly improve the estimate by taking the mean of the old estimate y and the value of x divided by y, where x is the value we want to draw the root from. So, it's, let's see that in action. For the value of x, in our example, would be two. Our initial estimation is one, as usual, so the initial quotient is two divided by one, that's two, the mean is 1.5. Now, we plug in 1.5 to our estimation, we get a new quotient of 1.33, a new mean that you'd see here and you'll see that it converges very quickly to the actual value of two. So now, we have an abstract algorithm. Let's see how we would put that into a function that computes that algorithm. A typical way to code algorithms in functional languages is to go step by step. So, we take a small task and formulate it as a function and then probably, that task will need further tasks that then would be defined in their own function. The first function we want to define is the actual iteration called the square root Iter, which says, well, if you have a guess and the value would be one to draw the root from, what do we do? Well, either we stop the iteration and return the result or we go and do another iteration step. The predicate that controls that we give it a name, let's call it, isGoodEnough. So, if my guess is good enough, then I just can return the guess. If my guess is not yet good enough, then I have to improve my guess. Let's do that with another function in prove and call, square root Iter again with the improved guess. Note that square root Iter is recursive so its right-hand side calls itself. One peculiarity in Scala is that the return type of a recursive function needs to be given always whereas, for other functions, it's optional. The reason for that is that to compute that return type, the Scala compiler would have to look at the right-hand side and because the square root Iter function is recursive it's stacked in a cycle. It would need the return type for that to compute the type for expression. To break the cycle, we require that recursive functions always have explicit return types. It actually makes sense even for other publicly used functions to give an explicitly return type because that's good documentation but it's not required by the language. Okay. So, let's implement this in practice. What we're going to see is a new way to write programs. So far, we have done everything in the repo. Now, for larger programs, we have something that is better adapted. We go into Eclipse and we start a worksheet. So, I take you through the steps one by one. Here, we have an empty Eclipse thing. We first start a new project the Scala project. Call it, demands a name, call it [unknown] for the course. And then, in the project what we can do is define a package, which is essentially a directory in which we are going to put all the stuff from this week. Call this Week one. We don't need to define packages but it's good practice to keep stuff tidy and ordered. And then, in that package, we define a new sheet. It needs a name, let's call it Session. In a worksheet, what we can do is we can type expressions and have them evaluated, just like in a repo. So, we can do one plus two and expressions get reevaluated when we hit Save, that will become [unknown] or Control+S. But the expressions show up on the right in a different column that you see here. We can also define functions, let's say, the absolute, absolute function that we've seen before. So, we could say, well, if x is less than zero - x else x And the repo would answer the, with the value of the absolute function, well, not the repo, the worksheet but the two are actually related. It's just a different mode of presentation. One thing we can do which is nice, nicer in the worksheet is we can actually go back and edit expressions and the reevaluation will then show the edited value. So, it's not just a single line editing window but a whole window that we can use. So, let's use the worksheet to complete our square root functions. The first thing I'm going to do is take it from the slide. So, I select square root Iter here and paste it inside the worksheet. I can reformat with Control+Shift+F. So, that would reformat things nicely. But the worksheet still doesn't compile because, of course, I have two functions here that I haven't yet defined that would be as good enough and improve. So, for isGoodEnough, let's do that first. So, is, isGoodEnough takes these same parameters as square root Iter, and it returns a bullion that says whether we can stop the iteration or whether we need more steps. So, what could that predicate be? Well, one way to do it would be to say, well, if we take the current guess here and we square it. If we are close enough to the original value x, then guess by itself would be close enough to the desired square root value. So, let's code that up. We would say, guess, guess - x, we would have to take the absolute value of that. And it would have to be smaller than some epsilon value of, say, 001 for the moment. Okay. So, that was number one. The second function we need to define is Improve. And that's now the core of the Newton method, we say, would say, well, it could take a guess and an X. And to improve the guess, what do we do? Well, we say, we need to take the mean of the value the current value of guess and the quotient of x divided by guess. So, to take the average, we would first sum the two values and then, divide by two. Good. Now, we have a worksheet that compiles. You see on the right-hand side, you see all of the types. The last function we need to define is square root itself. So, let's do that, what would that be? Well, it would be the square root iteration. With our first initial value, we said, that was 1.0 and x. Well, now, we have all the elements in place and we can start to test our function. Let's start with the square root of two and we get 1.4142. So, that looks right. Let's do another one. Square root of four, and we, we get something close to two, as we would expect. So, as an exercise, I would like you to think about the implementation we have so far and try to improve it. One thing to improve is that the, is good enough test is not very precise for small numbers. And it can lead to non-termination for very, very large numbers. So here, let me demonstrate that. And let's take a very small number. Let's say, one^-6. So, one / 1,000,000. So our square root, the square root we would expect to see is one over minus three. And actually what we see is 0.03. So, that's pretty far away from where we want to be. And the other problem we have is if we take a large one, let's say, one to the 60th power. What would we see then? Well, actually what we'd see is non-termination. You see this here, with this little bar? That's as well, it doesn't find the square root. Not so good. Let me take that out with an escape. So, can you explain why that is? Why is the, is good enough test not precise for small numbers and why can it lead to non-termination for very large numbers? And secondly, can you define a different version of isGoodEnough that doesn't have these problems? Here are some numbers to test your, your version, some very small and some very large numbers. So, to answer that exercise, let's go back to our worksheet. The problem, we had for both small numbers and, and large numbers was that our isGoodEnough test is, takes an absolute difference. It asks whether the absolute difference between the square of guess and X is less than some threshold value. And that's not very good for very, very small numbers because the number we want to find in the square root might, might even be smaller than that. So, that, relatively speaking, that epsilon value might be huge compared to the number we want to find. And for very large numbers, we have the opposite problem, which is that very large floating point numbers have, can actually be further apart than this epsilon value. That means in the 52-bits, they have available for the [unknown]. It could be that the distance between one number and the next is actually larger than 0.001. And in that case, of course the iteration can never stop because, simply because there is no value that's ever good enough. So, we can solve both problems by making the test proportional to x. And that's very simply done by saying, okay, let's divide the absolute difference by the current value of x and let's make that be smaller than the threshold value. So, once I've done that, I can simply reevaluate my spreadsheet. And now, I will see that everything computes nicely. And for the small number, I get something very close to one^e-3 as expected, and for the large numbe, I get something like e1 to e30, and that's also as expected.