[MUSIC] Let's talk some more about parentheses, and let's particularly understand that parentheses are not optional in Racket. They are common, but every time we use them they have a meaning. So this is a habit you have to break yourself of. In languages that don't have a syntax like Racket, you're used to just putting in extra parentheses to help you understand something, and if something isn't working, maybe you'll just put in more parentheses and then it will start working. It doesn't work in Racket. The parentheses always have a meaning. In particular, in most places, if you write in, something in parentheses that means evaluate e To a result, and then call it as a function with 0 arguments because the way we do a function call is parenthesis, thing you want to call, and then argument. So if there are no arguments, this is call it with 0 arguments. So, look at this one with 2 parentheses. This says evaluate e, call the result as a function with 0 arguments. Get back a result and call that as a function with zero arguments. This makes perfect sense. We might even do things like this, but if it's not what you mean, you're going to get an error message. You're going to try to treat something as a function that is not a function. Now without static typing, this sort of thing will work just fine when you save your file, when you click run, but once you actually execute the code, maybe it's inside a function body somewhere, then you can get an error message. It can be hard to diagnose and your first reaction is to just start playing with the parentheses, and it's only going to get you into more trouble. So let's work through some examples to give you some practice with this. And the moral of the story is always, slow down, think about your parentheses. If you're confused why they're there, delete them and start over. Indent your code well, it'll always work fine. So what I'm going to do is just show you a bunch of versions of a factorial function, 1 of my favorite little functions for examples. And I'm going to start by getting it correct, okay. So, so far what I've written while I was talking to you is In factors of one argument function, so these parenthesis have to be here. Then, I have an if, and I need 3 arguments. This is the first one. It's a call to the equals function. This is the second one, which is 1. And then this is the third one, which is multiplication of n. And then another call. Always put a parenthesis before the call, a fact, to get the argument to that I need to call minus with n and 1, close, close, close, close close. And let's run this, and if I do fact of 5, I get 120 in, and if I do fact of 10 I think I get about 300,000. Oh, 3, 3.6 million excuse me. Okay? So, that version was right. Now, let's do a bunch of versions that are wrong, and try to figure out why. So let me do, I'll call it fact 1. N if equal n 0, then 1, else n fact 1 of -n1, close everything, and run it. It all seems to be fine. I call fact one with five, [COUGH] and I get procedure application expected procedure given one. No arguments, and that's exactly right. If you look up here, what I did while I was talking to you and typing is I put this 1 in parentheses, and as an expression, that means call 1 as a function with no arguments. There's no type checker to separate our functions from our integers, but when we went execute this in the base case when 1 was 0 That's when we got the error. So, we had already made about five recursive calls, and then we got the error. And we would fix this us by deleting these parentheses. We can just leave this in here, because As long as we don't call that function, it won't be a problem. Let me show you a small variant is fact1b. Suppose I made the same mistake. Alright, just like this. Alright, so you might think, if you're not paying very careful attention, that this fact1b is exactly like the first line, and yet it totally seams to work. In fact, this will work for almost every argument. The only argument it won't work for is 0. So what's going on here? well here I, I, I actually made a totally different mistake, this is wrong. If you call fact1b with a 0 you will try to apply 1 with 0 argument, but I'm not actually using fact1b recursively here, I, I wrote fact here, right. I didn't write fact1b I wrote fact, and so in fact pardon the pun, when I call fact1b with 5 I end up not calling fact1b again but going up to this first correct version. And so that's why we didn't get the error unless we called fact1b originally with 0, okay. Good, let's try another 1 how about fact2 excuse me. I need this parenthesis here. how about if = n 01. Otherwise, n of fact 2. I will remember, now, to call the correct thing recursively. [SOUND]. And like that, and click run. And this is actually a syntax error. So this, it will not allow. To start. I don't have to test it out to get an error. Dr. Racket will detect that, with a good error message here. If has five parts after the keyword. If is always supposed to have three parts, and yet clearly, syntactically, it has five, equal n zero, one, and this multiplication. And that makes no sense, If has to have three and what happened is I forgot the parenthesis around the function call to equal, ok? How about if I do it this way? If, so I'm going to get almost all of this right. Three terms multiplied by N fact of minus N one. Just like this, click run, and I get bad syntax multiple expressions after identifier, indeed I do. So if I say define in a variable, notice I forgot this parenthesis after the fact3, then it's expecting like a val binding in ML, right, that I evaluate something here. But I have 2 things after the variable, this is the first one, this is the second one, right. I messed up 1 parenthesis, this left parenthesis is supposed to be over here before the name of the function, not before the argument. Okay, parenthesis matter, I know I am typing fast in order to keep the video short but you should think which concerts am I using. And in this case if you are defining a function you put a parenthesis before the function name. You do not put a parenthesis before the argument list. Look how it up here in the correct version I have this and then I have my function buddy. Ok, alright lets do another one this one oh so I need to comment these out these ones so I can get the other ones to go ahead and click run so I can test them out. Here is my fourth version of fact how about if equals zero one other wise Multiply n by my recursive call to fact 4, with -n and 1. [SOUND]. Click run. This compiles just fine. Call fact 4 was zero. I get the right thing, 1. But if I call fact 4 with 5, I get an error message. And it says that * expects type number as second argument, given procedure fact4. That's exactly right. So, it turns out, that multiplication, we saw back in our first or second segment on Racket, can take any number of arguments, and here I'm passing it three arguments, n, the function fact4, and n - 1. Functions are first class, so you can pass them to other functions, but then the body of multiply says wait a minute, I don't have a number. I'm going to raise an error. A typechecker in a language like ML would catch this. In Racket, we have to test our functions to test this sort of error, then we need to fix up our parentheses. we need an extra parenthesis before fact4. And then a after it in order to call multiply with two arguments not three. OK let's do a couple more here's fact five n if equal n zero one otherwise multiply n by fact five minus N one. So here, we saw in fact four we had too few parenthesis. It made us annoyed. We just wanted to get our homework done so we added some more. The problem of course is this still works, but we added too many. And what it says is Procedure Fact five expects one argument given zero. That's exactly right, right here. I'm calling fact 5 with zero arguments. Fact 5 which I'm defining recursively right here, expects one argument. You are not allowed to call functions with the wrong number of arguments, and we get an error. And then let's do one last one, just because it's good practice. n times, so this is a very natural thing to do, because we've all grown accustomed to writing arithmetic a certain way. And you can probably see the error this time. I wrote * second. That's supposed to be the function I'm calling. Instead, what do you think would happen here? Well, again, the base case is fine, but if n is not 0, then I'm going to try to treat n as a function. So it expects some sort of error message where the number I called fact 6 with is trying to be called with some arguments, alright? When you look at your code carefully you can sometimes come up with a better error message then you would get from a system that has no idea what it is your trying to do. Here I think it will actually do a pretty good job. So the procedure application, expected procedure given one arguments where procedure times 1. And, what actually happened is, you would think this happened when n would be 5. Why, why does it say given 5? Well, it never got to this call. It went ahead and did the recursion, and that did the recursion, and that did the recursion, and it's on the way back out of the recursion that it first detects the error. When it tries to say, 1 times, and the recursive result, 1. And if, I'm going to write this out here in Racket, you have 1*1, that's going to give the exact same error message, because it's going to say that it expected a procedure in that first position, and you have a 1.