[MUSIC] So, let's now jump in and get the Racket basics out of the way. Let's learn how to define functions, variables, conditionals, and so forth, covering a lot of the ground we already did in ML. I have a few slides posted with this lecture but I think I'll primarily just stay over here in Dr. Racket and write a bunch of code with you. So, I already have #lang Racket, and this thing, so that I could test in a second file if I wanted to, although we'll just use the RPL here. And now, let's do a couple of variable definitions. So, (define, the name of the variable you want to define, and then an expression that you evaluate to the variable. So, this is really like, val x=3 in ML, okay? And now, we can do another one. So, a definition can use x. So, suppose I want y to be x+2. So, what I do is I call the plus function with x and 2. The way you call a function in Racket is you write parenthesis, the function you want to call, and then the arguments. So, plus plus is really just a function so plus is a function and we call it here. So, this variable y is being bound to the result of this function call and in general, function calls are written with a perenthesis before the function your calling, then the argument, then a parenthesis after the arguments. It's a different syntax than in languages you may be familiar with but that is a function call calling the plus function with x and 2. So now, let's define our own function. Let's I'm going to write a few versions of the cubing function, so I'll call this one cube1, and now I'm defining a function. So, what I'm going to do is I use this key word lambda, it's spelled like the Greek letter. Racket, in earlier dialects of this language, like Scheme have been using that Greek letter for decades, it's a bit of a strange choice. Then, the arguments in parenthesis, so this will take one argument. So, lambda is a keyword that says I wanted to find a function, put the arguments in parenthesis, and then you have the body. And the body I want is to call the multiply function with two arguments. With x and with the result of this other call x and x. And then, and that call, this call the lambda form and the defined form. So, this body, the, just the body here this part here would be like in other languages writing x times x times x. But in Racket, everything always has the function first, and all these operators are just functions, and so it looks like this. We get very used to in Racket, ending things with lots of parenthesis. I'll talk more about parenthesis in a future segment, but for now, notice all I did was introduce a val binding, right, for cube1 and bind it to this anonymous function. So, lambda is like ML's fn, right? It takes in, this an anonymous function that takes in one argument, x, and has this body that ends up cubing x, alright? Let me write a nicer version. It turns out that you don't have to write it that way because the multiplication function, which is provided to us already by Racket, can take any number of arguments and it returns their product. So, we really kind of just write it like that. So, multiply, in this language, is a function that can take any number of arguments. There is a way in Racket to define your own functions that take any number of arguments but I'm not planning to show that to you. You can consult it the guide, if you need it you won't need it for any of our homeworks. the other thing I wanted to point out here, is that this really is just a function call and so it makes sense that we're calling it that way. Our function cube2 takes one argument, multiply takes any number of arguments. Unlike in ML, I'm not lying to you, this is not syntactic sugar. In Racket, our a functions really do take 0, 1, 2, 3, 4 or any number of arguments. It's not syntactic sugar for coupling or for currying, okay? let me show you something that we do have syntactic sugar for though, you do not have to write lambda every time, if you want to do this. This is exactly like the previous version. So, what you can do is instead of essentially defining a variable and binding it to this anonymous function, you can use this syntax instead, but it is exactly the same thing. This is syntactic sugar for define the variable cube3 to be bound to a function that takes one argument x, and returns, has this as its body, x times x times x. If you had multiple arguments here, you could just do like that before that first right parenthesis. So, there are three versions of cubing functions. Now, let's write some recursive functions. It turns out that unlike in ML, we don't need anything new to do recursive functions, but you can just use the lambdas like we have been doing or the syntactic sugar I just showed you. So, if I wanted to find the exponentiation function, I'm going to do this two different ways. So, I'll call this pow1. The purpose here is x to the yth power and I think my solution y only works if y is non-negative, alright? I just need a body here and now I need an if. the way you write an if in Racket, is you write left parenthesis if and then three expressions. You want e2, e3, and that is the thing to test for. The true branch and the true, false branch, so we don't use keys then and else, so they don't exist in Racket, we just write the three expressions in a row and then end with a right parenthesis. So, the way I want to do this, I want to say if y=0, equals is function that takes two numbers, returns true if they're equal then 1. So, I've written two of my three expressions for if. And now my third one can be * x. and then recursively call pow1 with x and y-1. Notice that like every operator in Racket, minus goes first. And, there it is. So, pow1 is a function that takes two arguments, x and y, and its body is this if expression, this, sorry, if expression. The if expression has equal y0, for its first sub expression, 1 for the second and multiplying x by the result of this call, this call, pow1 with x and y-1. so this is the exponentiation function. You'll notice that we, every time we have a function call, its parenthesis function you want to call, arguments, okay? So, this will work fine. Why don't we go ahead and run this? I haven't been running much for you. So, I just clicked Run. Now, I can say pow1, how about 3^2, right? So, it's a function call. I pass in the two arguments. I get nine. And if I ask pow1 3^0, I would get one, great, okay? So, let's define just a couple more functions. let's do another version of pow, that's curried. So, currying has nothing to do with anything other than an idiom with closures. and so we can, we can do that in Racket. it's not as common in Racket because Racket has built-in support for multi-argument functions but there's no reason why we can't use curreying so let's see. Well, here's a simple version. I could just call pow1 with the two argument, right? So, this pow2 is a function that takes in one argument, x. Its body is this lambda, which returns a function that takes an argument y and then I just call pow1 with x and y. Of course, I could have my own conditional down here if I preferred, okay? And now that I have this this pow2, I could partially apply it and I could say something like pow2 3, okay? And if I save all that and run it I could say, three-to-the with 2, and I would get 9, right? Because I end up, taking this function that pow2 return, calling it with 2. That ends up calling pow1 with 3 and 2, and I get 9. So, it's currying exactly like an ML. because it's less common, if you're not partially applying things you know, so if I wanted 16, it's quite convenient to call pow1 with 4 and 2. But if I want to do it with pow2 well, what do I need to do? I need to call pow2 with 4. That gives back a function and now, I need to call that function with 2. This parenthesis matter. Parenthesis always matter in Racket. If I want to call pow2 with 4, I have to write it like this, then that gives me back something that is the function, and if I want to call that function with 2, I need this parenthesis to its left and then here. So, it turns out that in Racket, there's a little bit of syntactic sugar for defining curried functions. The code posted with this segment will have that. You don't need to use it. We're actually not going to use currying so much in Racket. there is no syntactic sugar for calling a curried function. This line that I have here, really is the best that you can do. I bring up currying here, both because it's something familiar and I wanted you to see it in multiple languages. And also, because it emphasizes that we have anonymous functions, first class functions, and whenever you want to call a function, it's always, e0, so parenthesis e0, for the expression that evaluates to the function you want to call, then e1 up to en for the arguments, then the other parenthesis. This is what function calls look like in Racket. Now, if e0 is not an expression, if it's something like if or define or lambda, then those are not function calls, those are other constructs in Racket. We'll continue to see those and understand those in the segments ahead.