In this unit, we are going to stay with the square root example and learn several techniques how to organize it better. So, I've written all the essential things we did last week into this editor in a program called sqrt.scala. So you see here the square method, the sqrItter improve isGoodEnough and finally sqrt. We can also add a test method, so here's the test method and we can also run it. Let's open the debug console here and that gives us the number of the sqrt of two as expected. Now, things are fine so far, but there's one problem and that problem is that we have many many functions that essentially all sit here equals one is equal to the other and they're all together pollute a little bit global name space. So in fact it's good programming style to split up a task into many small functions. We've seen that in the last week, but it turns out that the names of the functions sqrtIter, improve and isGoodEnough, there really matter only for the implementation of sqrt, not for its usage. So normally we wouldn't like users to access these functions directly. So if a user shouldn't access the functions, then why should there be there visible and comparable to the user? So we can achieve the hiding of the function and avoid name space pollution by putting the auxiliary functions inside sqrt. So let me do that in this example, I take sqrt, put it on top and then put everything inside. So now it's going to look like this. So here you see that the sqrtIter, improve and isGoodEnough. The now all inside sqrt and sqrt itself, the body of sqrt, it consists of this last statement which in turn is called sqrtIter and starts the iteration. So what we've seen here is a block, a block is delimited by braces. Here's a simple example of another block. It can contain definitions, like a val definition here or in the sqrt example we've seen several def definitions and then it ends in a final expression and that expression is the result of the block. A block is itself an expression, so a block can appear everywhere an expression can. And furthermore in Scala 3, the braces are optional around the correctly indented expression that appears after equals, then else and so on. So we can also write sqrt like this, we can leave out the braces and have it look a little bit cleaner. So blocks influence visibility, in fact, the definitions inside a block are only visible from within the block, they cannot be accessed from the outside. And furthermore the definitions inside a block shadow definitions of the same names outside the block. So, for instance, in this case here, the value x, it would go to this x which is the definition inside the block which is implied by the indetation here. It wouldn't go to this outer x, the outer x is essentially shadowed. So that that's a shadow from the inner x that essentially hides the outer x here. So let's put this to an exercise, we have another program here, lots of users of x and y. What's the value of result in that program? Take a look and digest a little bit and then answer. The possible answers are 0, 16, 32 or reduction does not terminate. So let's see, the result expression consists of the y plus x. So where does the why go to? The y gets access the y here, it certainly doesn't see the y here because that's a parameter, so it's local to the def here. Where does the x go? While the latest definition of the x was here but again, the x's inside the block which is implied here, so it's not visible at this point, so that means the x goes here. Okay, so the x is definitely zero here. What's the value of y? Well, the value of y says it defines its own local x, which is f(3). f(3) would be the parameter 3 plus 2y, so that put 3 plus 1 equals 4 and then it returns x times x so that's 16. So 16 plus zero is 16, so 16 is the correct answer. So one consequence of Lexical Scoping is that definitions of outer blocks are visible inside a block unless they are shadowed. And that's actually very useful because that lets us simplify sqrt by eliminating redundant occurrences of the same parameter, the x parameter, which means everywhere the same thing. So we see here that the parameter x is repeated all over again and it's always the same value, is always passed as x again to the results. So what we can also do is we can simply delete it in all the nested occurrences here, here and here and the program would still work. Now if we get errors, why do we get errors? Well, because we have passed it on and we no longer need to pass it on because it's no longer a parameter. So we can simplify the calling positions as well. Now we have a program which is shorter, clearer and that's exactly the same as the previous one. So so far we have seen definitions and expressions and definitions and expressions together are called statements. And again so far we used one line per statement, every statement was on its own line. But in fact we can write more than one statement on the line but then they need to be separated by a semicolon. So here you have an example, you can have a definition of y and then you immediately follow that with the expression y times y but here you need to semicolon otherwise it wouldn't work. Semicolons can be written at the end of lines, but are usually left out. So if you write this, then that's probably means that the person came recently from a language that required semicolons such as Java and isn't yet used to the new style that leaves the semicolons out. In fact, one way to use scala is very much as an imperative and object oriented language in the style of let's say Java or C Sharp. And if you use it that way, then often people say Scala is like Java without the semicolons because you don't need the semicolons. But in fact there's much much more to Scala and two functional programming, so this is essentially just typically the first steps in the long journey towards a completely different programming style. So in summary, you've seen simple elements of functional programming in this Scala language. We've seen arithmetic and boolean expressions, we've seen if-then-else conditional expressions, we've seen functions and recursion and we've seen nesting and lexical scope. You've learned the difference between call-by-name and call-by-value, which is two really important concepts. And even more importantly, you've learned a way to reason about program execution, reduce expressions using the substitution model. This model will be an important tool for the coming sessions