So welcome to our last language specification unit in which we're going to discuss everything that goes into methods. And, as you know, a lot goes into methods, right? Variables, subroutine calls, arrays, strings. We have to describe this hodgepodge, and we try to do it as painlessly as possible. So in the last unit we talked about classes, and we mentioned that the end with subroutine declarations. And these subroutines are either constructors, methods or functions. They all have exactly the same declaration syntax. Subroutines inject is a conceptual name that we use to describe the three kinds of methods, if you will, that the language supports which are constructors, methods and functions. They have different purposes, but at the same time they have exactly the same declaration syntax. Constructors are designed to create new objects. Methods are designed to operate on the current object and functions are similar to see functions in the sense that they don't understand what an object is, and they simply deliver some computational services. All these different subroutines must be typed and they must return a value. So you may wonder what happens with a void subroutine. Is a void subroutine supposed to return a value? Well, the answer is yes and no. And no, because you must say return at the end, and there seems to be no value. And yes, because essentially you're returning null. And so we can think about return is a shorthand for return null command. So, once again, all subroutines must return some value. The same is true for other languages as well, although in other languages, it is statically covered or implicit. Implicitly down under the surface so we void method in Java for example has no return command but in fact does have a return which is planted by the compiler as we'll see when we write the compiler. All right, constructors are somewhat privileged methods that have their own strange rules. And a constructor once again is designed to create new object, there maybe zero, one or more constructors in a class. For example, if a class contains only functions there will be no constructor in that class. The common name that the program has, Jack program has used for a constructor is new but if you have more than one constructor, you may need several u1, u2, u3 or maybe better and more descriptive names for these constructors. The type of the constructor must be the name of the class to which it belongs. And the constructor must return a value, like any other subroutine. But in the constructor's case, this value must be an object of the class type. So these are rules of the game when it comes to constructors. Okay, moving along, programs are rife with variables of which Jack offers four kinds. So we have static variables, which are sort of class-level variables that are seen by all the subroutines in the class. We have field variables that are also seen by all the methods and constructors in the class but not by their functions. Because a function doesn't understand what is a field. We have local variables which are use locally by a subroutines. And we have parameter variables which are essentially the same as local variables except that they can be initialized from the outside. And therefore they may be used to pass spectrometers from outside the class into the class. And all the variables must be typed and they much be declared before they are used. And as we pointed before the language is weekly typed so we can almost always assign a variable to any other variable, irrespective of their types, because once again, Jack is somewhat wild in that respect. I have here, I should say that in general in this unit, I lifted freely some text from the book and I'm not going to read all this stuff. You can stop the video and look at it or consult the book. So a few more, some more information about variables. And then let's move on to talk about statements, of which Jack offers five. We have a let statement for assignment purposes, we have if, while, do and return. Once again this was lifted from the book, you can stop and read it or look at the book. Which brings us to expressions. Now what is an expression? Well, 17 is an expression. 17 plus 3 is also an expression. And so is x plus 17. And so is x plus 17 in parentheses times y, and so on and so forth. So an expression is what you expect it to be. And because it has to capture so many different kinds of expressions, the definition of an expression is a little bit involved and the best way to do it is to use some recursive definition or some recursive language. So a Jack expression is either a constant or a variable that this keyword is also considered an expression. We may have an array indexed to some entry, which is also an expression. So for example, temperature 15 is sub-index 15 is an expression that presumably gives you the temperature in the 15th day in some array or something like that. And a subroutine call is also an expression. So for example, square root of 17, obviously, is an expression. And so is minus square root of 17 which brings me to the next definition that says that an expression which is prefixed by minus or by negation is also an expression. And obviously an expression plus an expression is an expression and so on and so forth using some other operators. And finally an expression within parenthesis is also an expression. So you may stop this and then look at it or once again, take a look at the book. And this is as much as I want to say about expressions. Subroutine calls are a little bit confusing because different languages have different rules. Although we get this to very quickly. And instead giving you all the rules, what I gave instead is a set of examples that I think are sufficiently rich to refer to any, well not any, but many different kinds of subroutine calls in Jack. And you're welcome to look at it, and maybe we'll do a quiz about it. There's some general syntax that you should follow. The most important thing to remember is that the number and type of arguments that you supply in your call must match those of the method signature or the sub-routine signature as is typically available through some API. All right, we'll end this long unit with the discussion of strings and arrays. And this will complete everything want to say about the Jack language. Strings are objects, and they are actually instances of a string class Which is part of the operating system. So as usual we'll describe by strings using an example. So what we see here in the first line is the declaration of string variable s that presumably at some point will be contains some sensible string or some nonsensical strings. And then we have a variable called C, which is primitive, it has the data type of character and I want to show you how we use both types of variables. Suppose we want to set s to the sting Hello World. Well we can do it in a several different ways. One of them which is the hard way is to construct the string using new, and to limit the string to at most 12 characters. And then we can use some loop or some hard wired statements. That populate the string with the characters H-E-L-L-O using something called a appenChar which is a method which is part of a string API. So that's one way of initializing a string or some value. Obviously, it's a very tedious way to initialize strings and given that strings are widely used and we don't want to write loops whenever we want to create a list. The compiler is nice enough to allow us to also say that s equals Hello World, which is very nice because it saves us a lot of trouble and yet you should understand that when this code is being translated into a lower level code the compiler would have to work hard and turn it into the chord that you saw previously or something like that. So what we usually do without even thinking about it is actually quite dramatic when it comes to implementation. And this way in which compilers sometimes hide complexity from the user is called a syntactic sugar, which is just a buzz word. The last thing that I want to show you is that we can extract an individual character from a string using this char et method. So essentially we showed how you can construct a string from characters. And we also showed how you can create a character from a string using the char et method. And if you want to learn more about string operations, you're welcome to explore the string API of the operating system. And finally we come to arrays and once again we'll stop with an example. So in this example, we declare in array called arr, and its string variable called helloworld which immediately goes on to contain the value Hello World. And then we create the array. We actually construct it and we tell Jack that we want to construct an array of length four. And then we do arr[0] = 12 which sounds completely sensible and harmless. But then we do something a little bit strange. We do arr[1] = false. And if you thought that this is strange the next thing that we do is even crazier. Because next we do arr[2] = fraction 314/100 which is some abbreviation of an approximation of pi. And if this was not enough, arr[3] is going to contain the string helloworld. So what do we show here? Well, we show in a, I think, a dramatic way that arrays in Jack are not typed. And therefore different entries of the same array can contain different data types. All these arrays of which we see one here are instances of an operating system class called array. They're unidimensional so if you want to implement the multidimensional array you should define and use an array of arrays similarly to the way it is done in Java, although the syntax in Jack is somewhat more cumbersome. All right so that's what I wanted to say about arrays and towards the end of this unit. I'd like to summarize some, but not all, of the peculiar features of the Jack language of which you should be aware when you set out to write your program in Jack as we'll do in the final project of this module. So first of all we have this strange let prefix that we must use whenever we do assignments. So this something which you can easily get used to after you get a few compilation errors when you forget to do it. Same with do, when we call a method for its effect we use the term do unless the method returns a value and then we just we can assign the value to a variable called the let prefix. And once again we use these prefixes because it makes the writing of the compiler easier, as we'll see in the next module. The next requirement is that the body of a statement must be within thirty brackets even if it's just a single statement. So for example if you look at this piece of code here, return a is a single statement, but you must put it in curly brackets, and so is return minus a in this particular example. And this is actually good practice anyway. So it's not such a big price to pay to get used to this style of coding. All subroutine must end with a return, which is a little bit of pain because you'll forget to do it and you'll get some compilation errors. And once again I want to remind you that the same is true for any other language, but some languages are nice enough to do it implicitly so the programmer doesn't have to write the return command. In Jack you have to write it explicitly. Perhaps the strangest feature of Jack to many programmers is that there is no operator priority. And so, if you write, naively, two plus three times four and expect to get 14, well, you may well get, in this example 20. Because if we evaluate this from left to right. Two plus three is five times four is 20. And in general the result of such expressions are unpredictable because the language does not bother to specify an operate priority and it's left up to the compiler writer to decide if he or she wants to support operator priority which is not required. So how do you deal with this? Well, very simply, if you want to enforce priority of operations, you have to use parenthesis. So if you want to get 14 in this example and in general if you want multiplication to go before addition don't forget to use parenthesis. If you forget this little twist here you're going to get also some interesting bugs in your programs and therefore, if you get some exotic bugs in your program remember just to go back to this slide and check it maybe we'll see some information that will help you debug your program. And finally, I want to remind you that Jack is a weakly typed language, and much more weakly typed than industrial strength languages. Which makes it very powerful from one end, because the programmer can have complete control of the host hardware using the not complete but I think consider control of the host hardware using the pointers that can go wild as we do with great pleasure in the next modules in this course. And obviously this is very unsafe because you can bring the host machine to its knees metaphorically speaking. And yet in course Nand to Tetris this is a very desirable feature of the language because we want to treat the language and the surrounding hardware as an open lab in which you are allowed to do whatever you please. So that's the end of our Jack language specification and in the next unit we're going to discuss the art and practice of writing Jack programs and Jack applications on the hack platform.