Today's topic is very important one. As we address more sophisticated applications, our programs get bigger and bigger, and the problem of organizing the program. So that we can maintain it easily and add new code, it's a very important one. Topic of functions and libraries is the mechanism that we use to help us maintain and organize our programs. Let's look at some basic concepts. These are our basic building blocks for programming that we talked about and we're quite near the top now. What we want to talk about today is ways to reuse codes by developing it as independent modules, so that we can build big programs from small pieces. The idea is called Modular programming and it's been around for a long time. What we want to do is organize programs as independent modules that still do a job together. And the reason that we want to do that is, that it's easier to share and reuse code and to build bigger programs. People build huge programs with modular programming, where teams work together and what we need is tools to make the pieces fit well together. Now, this has been an idea that's been around for a long time. And it's really kind of a holy grail in software development. There's a lot of difficulties, and ideas can conflict and really get highly technical in the real world. So we have to navigate that as beginning programmers. For now, for this lecture, we're going to start with a very simple definition. We're going to talk about libraries, and a library is nothing more than a set of functions, for the purposes of this lecture. Actually, there's quite a bit more to it that we'll learn about in a few lectures, and a .java file can be a set of functions, but it can be more. So for now, we're just going to talk of them as doing the same thing, because we want to talk about modular programming that java files that contains sets of functions. Later on, we'll look at how modules implement data types which is a more general concept that even better supports modular programming. So we're talking Java functions, or also known as static methods. And so, that's like a mathematical function, takes some input arguments, returns an output value and it might cause some side effects. It's like a mathematical function but it's more general because of the side effects. And so, you're familiar with the use of mathematical functions to calculate formulas and what programmers do is to use functions to build modular programs. You're going to use some for both and we'll have examples like that in this lecture. So we've already seen plenty of examples so far. We've been using math.random and math.abs, and sine and cosine, tangents and so forth. And the integer ends parts and all those sorts of functions that are built in to Java. We've also been using our I/O libraries, which are sets of static methods. Libraries instead of functions and that's what our I/O libraries. And all those methods that we talked about for standard input, output draw are examples of sets of functions in Java libraries. And let alone, you've been defining a function called main, and we'll get into the details of that in just a second. So let's look at the anatomy of a function or in Java, it's called a static method. So this is the square root function that we implemented in the early lecture. So it's got a name, sqrt, it's got arguments. Every argument needs a type and a name and those come in parenthesis after the function name. It's got a return value, the value the function produces and that has to have a type. So in this case, it returns a value of type double. All of that together, I put public and static in front of it, is called the method signature. It tells you what you need to know, in order to use it or call it. And then, there's a Code, there's Java code which is the body of the method, this is the body of square root. And we looked at implementing that code when we first talked about while loops using Newton's method. The last thing in the code, usually as a return statement and it's just the word return followed by a value of the return type. So that's all the pieces of the method and now, we'll take a look at how it works. But first, let's but it together into a .java file. A library is a set of functions, not java files, library. So this is a modular library, the newton.java. So it's got the same name. The filename is the same as the class name. So that's Newton in this case. And then, this library consists of two functions, the square root method and the main method. And we'll look at how those interact in just a second. Now, we're just using this square root from lecture two just to illustrate the basics. You can use math.square root but right now, don't worry about the technical details, we're going to be talking about the flow of control and it'll come back to you as we go through it. Our key point for this lecture is functions provide a brand new way to control the flow of execution. When you look in detail, it seems a little complicated, but the use is very natural if you compare it to mathematical functions. Again, the idea is that we want to be able to reason about what our program's doing. In encapsulating small pieces of the computation and functions is going to help us do that. So in order to really understand what's going on, we have to talk about the concept of scope. The scope of a variable is the code that can refer to that variable by name. And when we have sets of functions, you can't refer to every variable anywhere. Such a variable would be called a global variable and we don't use those. In a Java library a variable scope is the code following its declaration in the same block. So for example, the argument variables, C and EPS in this function square root, their scope is all the code inside that function. The code following its declaration, which is in this case, it's in the signature in the same block. T, its scope, is only the statements following. Can't refer to t net code before it's declared, and you can't refer to any of those variables in this code down here, it's in a different block. It's gotta be in the same block, and it's gotta be after it. So here we've got an array a declared in main. And we've got some integer variables i. You can't refer to those in square root, they're out of scope, they're in a different block and we have two i's, they're actually different variables. Each one is for its own for loop but they're actually different variables named i. So each variable, what we want to try to do is limit the scope as much as possible, so that we can understand what the program is doing. If you could refer to a variable encode in another different block, very difficult to understand what's happening with the code in that block. So we try to keep the scope low, as much as we possibly can. Small blocks of code and functions help us do that. So let's look at the flow of control for a function call. This is the Newton program with the two methods and the point of this main program is to read in a bunch of arguments. And then, for each argument it goes through and then computes the square root and then prints it out. So the idea is when you call square root in the main program it transfers control to the function code. It declares the argument variables, initializes them with the values that you gave, then executes all the function code. Then, when the function is done, it returns right back to the calling code, the statement right after the coral with the return value assigned in place of the function name in the calling code. So it's supposed to complete the square root and then assign the value to x. We look at this in much more detail in the next slide but this is the basic overview. This is call pass by value other language insisted in use other methods but this is the one that we use in Java. Now, one thing all the programs that we've written so far, they somehow run. How do they run? The operating system calls main when we invoke a program with the Java command. So main's a function that's called by the operating system. And its arguments, the command line arguments, are supplied with precisely the same mechanism as the values of c and f provided to square root. Okay, so let's do a trace of the flow of control for this function. So suppose we call this with the command line arguments one, two and three. So this code here, picks off those command line arguments and puts them in an array. An array of doubles. So I goes from 0, 1 and 2 and picks off those three command line arguments and puts them in an array. Now, we go into the second for loop, which is going to go through and compute and print out the square root of each one of those numbers. So now, we start with i equals 0, that's a different i, remember. Not really consequential, a of i is 1.0. And so now, we are supposed to compute the square root of 1.0, and assign that to x. In order to do that, we go up into the square root code, where now D gets that value one point. Now, T gets that value, C, and then in this case there's nothing to do, so we just drop out of that y loop and we turn the value 1.0. And what happens there is then x gets assigned that value. And now, we go to this next statement and print that out, so that's the first result that's printed out. And we go back to the for loop, increment i, pick out the value 2.0, and then go back up to the square root code. And now in the square root code, we can trace the operation of that code to compute the square root of 2.0. It keeps averaging c over t and t, as we talked about in lecture two. And eventually, it gets to a point where it breaks out of the while loop, it's got a good approximately to the square root of 2, returns that value back to the main. That value now gets assigned to x, and then that's the value that's printed out as the second value. Back to the for loop for i equals two. We get the next number, a of i equals three and then, call square root of three. And again, we stay in the loop for a while to compute the square root of three. And eventually, break out of the while loop. We have a value to return, return that value. Assign it to x, and then print it. So that's a trace of the flow of control for computing the square root using a square root function. Now, we go and we're done with the array, and we end the execution. This is a much more complicated flow of control when we look at it in that detail but it's very natural to understand what this code is doing. We have said in the main that we want to print out the square root in that loop. And pretty natural to assume that what's going to happen is that it's going to execute that code to go ahead and compute the square root. So let's just look at just a couple of details to discuss the way arguments are passed in functions. So here's a really simple example that's supposed to compute the, well, it says cube, and it does i times i times i. It prints, takes the value in from the commune line and it prints a table of the energies from one to end in their cubes. And it does so by defining a function cube that takes i as an argument computes item item item and assigns it to j and returns j. So and again, you could do this for any function that you might want to implement, and that's an actually fine computation to do for lots of applications. Okay, what about this one? What happens when we compile and run this code? You have to think about that a little bit. These qiuz questions are really about scope. So what happens in this one is, is not even going to compile, because it's like declaring the same variable twice. When we declare int i is the argument, can't declare int i again. It'll say, it's already defined, so that one won't even compile. What about this one? Again, think a little bit about scope. Well, this isn't about scope, this is, you've gotta have a return statement. The function, that int cube() says, I'm going to return an int value. But there's no code to return anything, so that wouldn't even compile, it says, you're missing a return statement. Compiler's your friend, even for functions. So what about this one? So now we return it. So this one works. The i in cubed is declared and initialized as an argument It's different from the i in main, but we don't like to write code that changes function arguments. Even though it works, it's a little bit confusing. And some programming might not work. So we call that bad style. So instead, it works okay, but instead we prefer this style as compact code. We're going to just do our computation with that variable just as if we had declared it within the code block, and it produces the answer. So those are just a couple of examples, simple examples, showing how to implement and use functions. We'll look at some more complicated examples next.