Welcome to Module 3 of Nand to Tetris, in which we are going to discuss high-level programming in languages like Java and Python. However, we will not discuss these languages directly. Instead, we'll deal with the Jack language because we want you to participate in this fascinating process of not only using a high-level language, but also designing it from scratch and writing a compiler for it. And that's exactly what we'll do in Nand to Tetris. We'll build the language, Jack, from the ground up. However, in this module, we'll provide a top-down description of this language. And in general, here's the big picture of the course. And here's also the agenda of what we should expect from now on. This is the beginning of the end of the course. And we see that in the next two modules, in Modules 4 and 5, we are going to build the Jack compiler. And in the following module, we're going to build an operating system from the Hack Jack framework. And, therefore, it makes a lot of sense to begin by learning Jack, because Jack is going to play a dominant role in everything that we do from now on. We're going to write the Jack compiler. And also, the operating system that accompanies Jack is going to be written in Jack itself. Just like the operating system which accompanies C, Unix is written in the C programing language. All right, so with that in mind, let us review, once again, some Jack code that we saw in the introduction module to the course. There's no need, really, to read the code, or try to understand it. We'll show many more examples later on in the module. For now, I just want to observe, by looking at this code, that Jack is a simple Java-like language, if you wrote programs in Java everything should look kind of familiar. It has some peculiar syntax, which we will explain later on. It is an object-based language with no support for inheritance. It is a multipurpose language that can be used to design any application that comes to your mind. It lends itself nicely, in particular, to simple interactive apps like Tetris, Snake, Space Invaders, and so on. And it can be learned, and I should add also, unlearned, in about an hour, which is extremely important. Because Jack, in itself, is not an end but rather a means through which we're going to learn a lot about how to write a compiler and how to write an operating system. All right, so the take home lessons of this module are many. First of all, you will learn how high-level languages are designed and implemented. We will learn how to handle primitive and class types behind the scene. How to create, represent, and dispose objects. And this will give you a lot of insight about all sorts of possible bugs like stack overflow, and memory leaks, and so on. We'll learn how to deal with strings and collections like arrays and lists. And we also learn how the high-level language interacts with the host operating system, as well as many more things about high-level languages. In addition, you will continue to develop your programming skills. We'll write a non-trivial program using the Jack language. And we'll continue to discuss this super important obstruction implementation principle, which sort of is a threaded throughout the Nand to Tetris courses. Jack is by and large a self-explanatory language. And therefore, I think that the best way to introduce it is to see some examples. So we'll go through four examples and in each one I will use the example in order to introduce some features of the language. So let us start with Hello world. And Hello world is a program that we saw before. If we execute it, we get this very imaginative text, Hello world, on the screen. But for now, what I'd like to observe is that, in Jack, we have three kinds of comments. We have API comments, which can be processed by some external tool, like a Javadoc. I mean we could have written a similar Jackdoc tool. We have block comments, which are delimited by these two limiters. And we have inline comments, which are used for internal documentation. In addition, we have white space, we can use as many space characters as we want in our code. And we exploit this white space and the fact that it's ignored by the compiler in order to use indentation. And indentation, of course, is super important in order to help us make sense of our code and the code of other programmers. All right, moving along. Let's see another example of a Jack program, a more interesting one. And this program wants to read a set of numbers and compute their average. Now, in order to illustrate this program, we need an output device. So here it is. So let's start to look at the code. We begin by declaring a bunch of variables, an Array variable called a, and three integer variables. And then we go on to ask the user, how many numbers do you want to enter? And the user says three, or let us assume that the user says three. Well, based on this information, we construct an array of size three. We set some variable to 0, and then we enter a loop in which we continue to prompt the user to enter numbers. Let us assume that the user entered the numbers 12, 8, and 5. And let's see, the average of 25 is 8 point something. And indeed, when we print the average, we get the result 8, which makes sense because in Jack, or in this program and in Jack in general, we deal only with the integer data types when it comes to numbers. So what we've seen here is an example of procedural processing. Nothing here is super interesting. It is very similar to any other language that you played with in the past. But still, we can make some important observations. Okay, first of all, a Jack program or a Jack application is defined as a collection of classes, one or more classes. And one of these classes must be called Main. And within this Main class, there should be at least one function, and this function must be called main with a lowercase m. And this Main.main serves as the entry point to the Jack application. So if you had this class residing in some directory or folder on your computer along with some other classes, if you would tell the runtime system to execute this directory, it will start executing everything from Main.main. All right, moving along. We see that we have control structures. And indeed, the Jack language provides control structures like if, while, and do. And obviously, whenever you want to do something meaningful you have to use these structures. We also see that we have array processing. And in Jack, arrays are implemented as instances of an array class, which is part of the host operating system. And interestingly, Jack arrays are not typed so they can contain any value of any type that you can think of within the very same array, which is a little bit peculiar, but we will use it in all sorts of interesting ways down the road. What else do we see here? We see that we have some operating system calls, right? And methods like Keyboard.readInt, and Output.printString and so on. Well, these methods belong to the host operating system, and we can use them at will in our Jack code. And we'll have a lot to say about this down the road. What else? Well, we also have data types. And if we focus on these three lines of code, we see that we have primitive data types like int that appears in this program, and in other programs you will see more data types like char and boolean. And we also have some class types, or we may have class types, like the array class that I mentioned before, this is also a legitimate type in Jack programs. So in Jack programs, you will often see class types which come from the operating system. But the programmer is free to invent as many more classes and class types as he or she pleases. And in this sense, Jack has an unlimited data typing capability. All right, this is the end of this unit. Throughout the unit, we saw two very simple examples of Jack programming. And in fact, what we saw is how an object-oriented language can be used to write code that has no object and no object orientation but just very simple, plain sequential processing. In the next examples, we'll begin to push the limit on what can be done with object-based programming, beginning with the next unit.