In the previous module, we saw two examples of simple procedural programming. And now, we go on to discuss object-based programming. Now, before we start, I'd like to say a word of caution. Beginning with this module, we are going to see some nontrivial examples of computer programs, of object-oriented programming. And I'm not going to spend too much time explaining what the programs are doing. And that is because this course is not about programming. It's about how programming languages are designed and implemented. And yet the best way to explain these design and implementation issues, is to show many programming examples. So I think the contract between us should be such that you should be willing to go with the flow. See my examples without trying to understand every statement and knowing that whenever you want you can stop the video and look at the code in depth. Although I recommend doing it only at the end of the unit, so that the flow of the presentation will not be impaired. So once again, the code itself is not super important. What's important are the principles, that I will make sure to highlight to everyone every once in a while. All right, so in the previous module. One thing that we said is that Jack has a very limited primitive type system. It has only three types and only one numeric type, which is int. In Java we have I think five numeric types, and yet we have only one. So it makes sense to extend the language with the ability to represent more numeric types. For example, rational numbers. So it may be nice to invent some fraction abstraction that allows us to carry out such operations as you see here without loss of accuracy, so that everything will be as correct as possible. So we can do this by introducing some fraction API as you see here. So what we see hers is skeleton of a class, that represents fractions and provides a variety of fraction oriented functionality. And what this API lets us do, is first of all we could read the code. The code here is of course just method signatures. So we have a constructor that allows us to create new fractions. We have two accessors that give us access to the numerator and denominator of the current fraction. We have a plus method that enables us to add up our fractions. We have a dispose method that gets rid of the memory resources that were allocated to this fraction, and we have a print method that prints the method on the screen. Now obviously if you were to design such an API, you may want to add more functionality. Not only plus, but also minus, multiply, divide, invert, and so on. There are lots of things that you may want to do with fractions and yet once again, this is not a course about programming. And yet I'm going to give you enough information. So that if you want, you can implement all these additional functionalities also. Once again, not necessarily for this course. All right so how do you use this API? Well you need to write some client code and here's an example of some client code which exists in a separate Jack class. And this program here seeks to add up two-thirds and one-fifth, and it does it as follows. First of all it creates three pointer variables, or reference variables, or object variables. Any one of these terms is correct. A, B, and C, of type fraction. And then it creates a two fractions, A and B. A points to the fraction two and three. The fraction characterize by two and three, and B points to the fraction characterize by one and five. And then we do A plus B, we print the result and we return. So at the end of the story when we execute this program. We're going to get 13 over 15, which hopefully is the sum of two-thirds and one-fifth. What I'd like to do next is focus on every one of the activities that we did here in some details. So we'll talk about object construction, we'll talk about methods that manipulate the current object and we'll talk about object destruction. But before we get into these detailed explanations I'd like to make a general comment. And the comment is that here, once again we meet the super important abstraction implementation principle which we emphasize throughout this course. Notice that users of the fraction abstraction need to know absolutely nothing about how the fractions are actually implemented. They view the fraction as a black box abstraction. And they just use the services of this abstraction as advertised in the abstraction's API, and that's perfectly okay. That's how we use abstractions in high level programming. And yet at some point, someone has to implement this abstraction. This someone may be you, at a different stage of the project. It may be another programmer who works in the same team together with you. Or it may be someone in another company that was hired in order to develop this abstraction. So let us now take off the hat of the application programmer that writes the client code and put on the cap of the abstraction implementer. The person who has to actually build the fraction abstraction and realize it can inject. So let's do that. The first thing that you have to ask yourself when you design an abstraction is, what kind of data do we want to store about the objects that this class is supposed to represent. When the case of fractions, we need two pieces of data which is the numerator and the denominator. And we in store these values into integer type of fields. And these fields are akin to what Java calls member variables and what the C# calls properties. Now, these are simply variables that describe the data elements of the objects or the instances of this class. Okay, moving along I show you here two accessors that I wrote in order to facilitate access. To these field values, to the values of the current object. Now, this is common programming practice in object-oriented programming, but in Jack it's absolutely necessary because the only way to access field values from outside the class is through accessor methods. So let me give you an example where this principle comes to play. Suppose you want to create the fraction 5 over 17 and you want to access numerator of this fraction. Well, in a language like Java you could have done this. If the member variable that represents numerator and denominator were public, you could have done x.numerator and get the value of this field but in Jack this kind of access is disallowed. And the only way to achieve the same purpose is to go through an accessor method, which is good programming practice anyway. So that's how we do things in Jack. All right, moving along let us assume that we've designed these two accessors, they're in the class. I'm not showing them because I don't have enough space on each slide. So everything that we discussed before in previous slides is already part of the class. The next part of the class is going to be a constructor. A method which is designed to create new objects. Well this constructor receives two inputs, two parameters x and y, and it goes on to populate the numerator and denominator of the current object, with the values of x and y. Then it reduces the fraction which is important in case the fraction is something like 8 over 16. We want to reduce it to one-half and finally it returns the base address to this object fraction which was just created. Now the reduce method is a typical method that operates on the fields of the current object. In this case, it reduces the fraction by using the function called GCD. And finally we have this function GCD which computes the greatest common denominator. Going back to reduce, once you compute the greatest common denominator of the numerator and the denominator, you can divide both by the GCD and get the reduced fraction. So here is the code of GCD which is the classical implementation of Euclid's algorithm. And with that I kind of like this slide because it shows you all the possible subroutines that are available in Jack. And these subroutines are methods, constructors and functions. Methods are designed to operate on the current object. Constructors are designed to create new objects which are instances of the current class. And functions are methods that operate on no object in particular, these are equivalent to static methods in JAVA. A few more things that we see here is first of all the keyword this, which is a standard reference to the current object. Internally it's actually a memory address, it's the base address of the current object in the host ram. And one of the rules of the game is that a Jack constructor must return the base address or must return an object of the type of the surrounding class or the class to which this constructor belongs. Now Java constructors do exactly the same but they do it implicitly. You don't have to say return this in Java but actually, believe me, this is what the constructor actually does after it follows compilation. All right another thing that we see here in this example, is that the Jack subroutine must always terminate with the return command. It doesn't matter if it returns a value or not, you must have a return. Once again in Java, there's no need to return explicitly. But once again, believe me, Java methods always return implicitly using some code that the compiler injected into the translated VM code. All right, moving along let us take a look at this method, plus. This method simply adds up the current object and the other object. The object that was passed to it as a parameter and the addition is based on elementary school mathematics, which I'm not going to dwell on. So this is an example of a typical method operating on fractions. And you could have written if you want many more such methods to do minus, multiply, divide, invert and so on. All right, the next thing that I want to explore is the print method, which prints the current object on the screen. Of course we don't know what is the current object, so 13 over 15 is just an example. Whatever object you will give this method, it will print it in this nice format. And the logic is trivial, it prints the numerator, it prints a slash, it prints the denominator and that's it. I'm putting two statements in the same line in order to save slide space in other slides so don't worry about it. And of course once again I can add more fraction methods here if I want. And the last method that I want to discuss is dispose, which is necessary in order to be a good citizen and free up the resources held by a fraction when you no longer need it. I'm talking to the application programmer who uses the services of the fraction plus. So the dispose method is implemented using a call to the host operating system. And in particular, we call an OS routine called deAlloc, which takes an address in memory and disposes the memory block that begins in this address in order to represent the current object. So once we pass this to .deAlloc, we are guaranteed that the memory resources that were held by the current object would be freed for future use of our computer system. And this is necessary in Jack because Jack has no garbage collection services like other languages may have. And therefore it is up to the programmer or it is up to the class architect to make sure that he or she includes a dispose method in every class that represents an object. So that the application programmers will be able to use it in order to get rid of objects that are no longer necessary. Now the next thing that I'd like to explore is how objects are really represented in memory. And the difference between the programmer's view of the project and of the object and the systems view of the object. So far, we took the roles of an application programmer. And we then took the role of the class developers. Now we'll take the role of the plumber. That really goes inside the pipes and trying to understand how things really work under the hood. All right, so I repeat here the constructor code that we saw earlier. Nothing new here. And some client code that uses the constructor by calling it twice. And programmers tend to think about objects using this visual representation here. So we see that each fraction is represented by a block that includes all the field values of the current object. And we also have a reference to each of these blocks, which is the name of the variable that we created in order to represent these fractions. So after running the client code, we get in the programmer's mind or using some documentation tool we'll get these to obstruct descriptions of the objects that we created. Now how is it really implemented under the hood? Well, here's how it really is implemented, we see the host RAM. We see that the RAM, some area of the RAM is designated to represent the stack of the currently running application. And this is the ranking stacks that includes everything, the variables, the memory segments and so on of all the methods up the calling chain. We have the heap where we represent objects and arrays. We see that we have a variable called a, which contains the number 15087. If we treat this variable as a pointer and we look up this address in the RAM, we see the number 2. If you look at the next word in the RAM we see the number 3 and these two numbers comprise the memory block that represents our first object, the object, well, first or second doesn't matter. Two over three. And then if we look at the b variable, we see that it contains the address 4112, if we look up this address, we get the same story, okay? So this is the real representation of these objects in the whole strand. All the addresses are contrived, I made them up and they're not important obviously for our discussion. Now there are some interesting issues here and the first one is how does this happen? How does this representation, how is it established? Well, the secret is that when the compiler is going to compile your constructor, it would inject some calls to the operating system. And these calls are going to find available memory and allocate it to the object that was just constructed. So as you will see later in the course, the compiler cooperates with the host OS in order to deliver this functionality that we see here. Which raises some more issues like well, how do we know, how does the OS know how to allocate memory? How does the OS know how to de-allocate memory when it is no longer necessary? Well, these are high questions and we will deal with them in the most elegant and satisfying way later on in the course. So stay tuned until we get to discuss them. Now I'd like to end this unit with a general observation about Jack. And if we can sort of look back at what we did, we wrote the class called fraction and what you see here is the entire code of this class. It consists of sort of one page of code, a quarter of which is comments and white space. And this goes to show you the tremendous expressive power of object-based programming in general and the Jack language in particular. We got a lot of functionality with very little code. In the next units, we'll continue to show you some more examples of elegant object-based programming. And as usual the purpose is not to talk too much about the programming but rather to talk about the language and its supporting infrastructure.