So if everything worked according to plan, then you have already gone through a machine language primer. And we are ready to move on and talk about what lies ahead. So here's the computer that we built in an Nand to Tetris part one. And launching Nand to Tetris part two, just like many other classical courses in computer science. We'll start with the familiar Hello World program. Which is written here in a language called Jack, a high-level object-based language that we will use in this course, Nand to Tetris part two. And so we write this program, we put it into the hack computer somehow. We click something and boom, the screen that displays the words Hello World. Well, in most courses at this point, students continue to develop some more interesting programs. But in Nand to Tetris, we stop right here and ask ourselves a whole set of interesting questions about what happens below the surface, so to speak. First of all, take a look at this whole notion of program execution, which is nothing short of magic. Because after all the program is just a bunch of dead characters that I wrote on a piece of paper or using some text editor, it's completely static. And all of a sudden, I can take this program and somehow transform it into a set of low-level instructions that cause the computer to actually do something. This is quite fascinating and we take it for granted. And how did the computer know how to display the words or the images hello world on the screen. How did it know how to display H on the screen and excuse me, how did it know to display a single pixel on the screen. All these are very interesting questions that we usually don't bother to think about. And what about keywords like class, function, do, while. We know exactly what we want the computer to do when we write these words. But how does the computer figure out what to do with them? How does it actually even pass our code and understand where these words are located? And even if it understands that it found a while and that while should suppose to signify a loop. How does the computer know how to execute this loop? And take a look at commands like printString and println. It looks like these commands are invoking methods or functions that exist in other classes, right? The class called Output. Which is presumably not here, it's part of some class library or an operating system. Well, how does the computer know how to pass control to these methods and then after they do the thing, return control to our program? All these issues and hundreds of similar other questions are extremely interesting. And important and yet high-level programmers don't stop for a minute to think about that. Why are they allowed to act in such a state of a bliss of ignorance. Well, the answer is that high-level programmers think about their high-level language as an abstraction. And the programs that they write as far as they are concerned are also abstractions. Now being able to hide, [COUGH] excuse me, being able to hide low-level technical details from the users of your system is an extremely important principle. Not only in computer science but in any large scale scientific or technological project. Because you see high-level programmers have enough problems of their own. And application programming is sufficiently interesting and challenging field of work and pleasure. And if we would expect high-level programmers to also think all the time about how to render pixels on the screen and process programs and so on, they will go nuts. They will not be able to focus on their own work. So it's actually a virtue that they don't have to think about the low-level. However, someone has to think about it. And someone has to, at some point, at least if you have any inquisitive mind. Then you should ask yourself, what makes these abstructions work? And the answer is that what makes them work are things like assembler, virtual machine, compiler and operating system. In closing this gap, understanding how these things work is what Nand to Tetris part two is all about. Now some of you might say well, I don't understand, Shimone just told me that in order to be an application programmer, I don't have to worry about these things. So why do I have to worry about these things? Well, the answer is that indeed you can write a very nice high-level programs without understanding compilers and operating system internals. And yet, if you do so, you will be stuck in a certain limited and constrained level of competence. However, if you will take the time to indulge yourself in understanding how these wonderful software layers work. You will become a far more competent and sophisticated software developer. And not only that, you will also become a much richer person intellectually speaking. Because in order to develop a VM, a compiler in operating system, you have to learn how to use some incredibly beautiful algorithms. Data structures, programming techniques and all sorts of things that will advance you tremendously. Not necessarily in understanding the lower level details, but in general, as a software developer. And as a thinker and also of course, as an applied computer scientist. All right, so with that in mind, here's the big picture, these are the major stations in our journey. And the last station is a high-level language and I would like to devote this unit to discussing the end of our journey. What will happen at the end? Well, at the end, we'll be able to write programs in the Jack language, which is quite similar to Java in many respects. And I would like to give you an example of how these programs will look like. So, I've chosen arbitrarily a little problem in playing with points in a two-dimensional space. So what we see here are the points p1 and p2. And the point p3 is the vector addition of p1 and p2. And it looks like we are interested in the distance between p1 and p3. How can we perform such manipulations using Jack? Well it turns out that someone has already written a class called Point. That includes various services which are quite useful in order to carry out such To the manipulations and this person gave me not only the class, he or she also gave me the API to this class. So I can use this API to write a little program that performs what you see here in the picture, and here is the program. So I open my text editor and I write these lines of code. I define a new class, I call it main. A new function, which is also called main. And then I declare three object variables called p1, p2, and p3. The type of these variables is point. And then I go on to construct p1 and p2. I know how to do it because I have the API. So I read the constructor signature and based on this I initialize and construct these two points and assign them to the object variables p1 and p2. And then I have to add up p1 and p2, I look at the API, there is a plus method. So I use it according to its signature, I get to construct a new point p3. And then for debugging purposes I print this point on the screen. If this program were running now which it doesn't yet but if it were running I would see hopefully four six on the screen. And then I print line and compute the distance, the Cartesian distance between p1 and p3, and I print it. I do it in the same statement and once again, if this were executed, I would see, hopefully, the number five and then I return, all right. So I used the point class as an obstruction and did some manipulations that did exactly what I wanted to do. And I think that this little example here shows you the tremendous power of object based programming because with something like ten lines of code I managed to do some very useful work. Provided of course that someone took the trouble to develop the Point class for me. So indeed what I'd like to do next is delve into the Point class, and let's do it. So the first thing that we do, when we open up the implementation of point, is that we see that we have some class level declarations. So, the class begins by declaring that x and y are, or let me put it otherwise. It begins by declaring that every object of type point is characterized by two numbers x and y, which are the coordinates of this point. And then there is a class level static variable called point count that stores how many point objects were designed or constructed so far. And now comes the constructor, the signature is the same as we had in the API, and here's the body of the constructor. There's nothing mysterious here, it looks very similar to Java or Python, if you are used to these languages. And the only difference, I guess, is that the constructor ends with an explicit return statement. Which is implicit in languages like Java and Python. And in this explicit statement, it returns the address of the object that it just created. And this address goes right into p1 and p2. In the colors code so everything works as expected. And let's continue to pursue this class, so this is what we've seen before. There are some accessors that I didn't bother to list in the API. Here is the definition of the plus method and you can look at the algebra later if you want and convince yourself that it indeed carries out vector addition. And let's see we also have this Cartesian distance method which uses the Pythagorean theorem and I think and then we have the print method and that's it. Now, there's an important point that I like to make so please look at me and not at the code. The point is that there's no point really in trying to get to much into the point class. Because the purpose of this unit is not to teach you Jack and neither is it to teach you object base programming. The purpose is just to give you a flavor of what object based programming in Jack is all about. And just to give you the feeling that it looks very similar to what you probably did in other programming languages in other introductory to computer science courses. So, Jack is quiet simple and sort of plain vanilla language for those of you who have some experience in programming. All right, so to recap what we had here is two classes Main.jack interacting with Point.jack in order to carry out some manipulations. And to remind you, we are now located at the last station of our journey. And what I'd like to pursue next is the question of how do we take this high level code and bring it all the way down to executable code that can actually run on our bare bone hardware. Well, here is how we do it. We take these classes Main and Point and we put them in some directory on our computer and we call it any name we want, I decided to call it points in plural. Then we apply the Jack compiler to this entire directory. As a result we will get two new files that have the same prefix names, the same class names but a VM extension instead of a Jack extension. And these two files will be in the same directory as our source code. And by the way, if you're use to Java this is exactly what to do with Java. Because you start with in Java it will be two Java classes that have a Java extension instead of a Jack extension. And after you apply Javac the Java compiler you will get two classes that are written in byte code. And the extension will be class, instead of VM just a small syntactic detail. And then, you probably don't it, but you're going to apply something called the VM Translator. Which in Java, is done using the command java, java itself. And in our world, the VM translator is going to translate the VM code into one file that contains many instructions in hack assembly. Then we can take this ASM file as you see here and give it to the assembler. The assembler will finally produce from it another file with the hack extension. And then we can take this file put it into the computer that we built in a NAND to Tetris Part I run it and voila. We're going to see the output or our program flickering on the screen in front of us. So that's the process of taking the high level program and moving it through the hoops until it gets into something that can be, actually, executed. And, during part two, not only we will do these things many times, we'll actually build all these tools ourselves. All right, so once again here's the course plan will start with module zero in which we ask you to get acquainted with hack assembly, very important to do it. And once we do this, we move on to the next two modules in which we build a virtual machine and a VM translator. And then we'll jump to the end of the journey, and we'll ask you to write some non-trivial program in Jack, obviously we'll teach you a lot about how to use the Jack language. Not too much, because Jack is self explanatory. But then you will use this language in order to develop some interactive game or some other simple program. And then once you understand the language itself, once you get familiar with the language itself, we'll write a compiler for this language for Jack or write the compiler using something like Java, or Phyton. A language that you are, you feel comfortable with. And then finally, in the last module of the course, we'll develop the operating system that provides all sorts of important extensions to Jack, and that closes as also the gap. Gaps between high level programming and the Barbone hardware. So before we take off in our nine to cactus path to journey, I'd like to say some words of disclaimer and run a little self-inspection together with him. So first of all, I want you to know that Nand to Tetris Part II is much more demanding than Nand to Tetris Part I. I think it's just as much fun as part I, but you will have to write many programs and do lots of projects. So you have to make the proper, I think, mental and time commitment to take a rigorous and challenging course, although it's going to be a lot of fun, and I think that you are going to enjoy it tremendously. But still, there's going to be a lot of work. Now, during this unit that we just went through, I showed you several examples of high-level programing using the Jack language, and I want to ask you the following question and please I wanted to answer it sincerely in your heart of hearts, so to speak. Are you comfortable seeing these programming examples? Do you feel comfortable with things like objects and constructors and feference variables and applying a new operation in languages like Java or C#. If the answer is yes. If you understand what the classes, methods, and constructors are and so on, then you're ready to take this course. If the answer is no, then I beg that you don't take calls and instead go and take some introduction to computer science course. Learn the in and outs and of high level programming using some decent object based language like Java or Python, and only then come back to us and complete Nand to Tetric Part II. Of course you can enjoy the lectures or at least some of them I hope without doing any projects, but then this will miss the purpose of this course, so once again If you feel comfortable fine, if not you should need some preparations. So if the answer is yes, then my next question is we also saw a quite few examples of low level programming throughout this unit. So, my question to you is do you feel comfortable with the low level programming using the Hack assembly language. Do you understand what A = M is, now what is A, what is M, what is the meaning of this operation? If the answer is no, then I request that you could back to the machine language primer, learn what you need from there according to my guidelines and do project four. Do this project, assign it, or submit it, get a grade on it, and then come back to continue to work on Nand to Tetris part two. If the answer to both questions is a resounding yes, then welcome aboard, you're ready to take Nand to Tetris part two. And, you can move ahead and actually start the course, and in the next unit we're going to talk about some compilation aspects, and then we'll start to actually build our visualization.