Hi everyone. Today we're going to talk about first-class functions. First-class functions meaning that functions are values. Unlike the languages that tree functions differently from other values like integers, strings, and Boolean values, first-class functions are just values in the language with first-class functions. Meaning that functions can be paste as function arguments and functions can be returned as function called results. If you remember, F1 VAE treated functions differently because they were first-order functions. They were not first-class citizens. But now languages with first-class functions, functions are just like other values and we're going to learn that today. Now, you are supposed to read Chapter 9; first-class functions for this material. Before explaining first-class functions, let's review whether you understood F1 VAE functions as non values first-order functions well or not. Questions and answers, let's try. In the first example, we defined a function twice, and we call the function in the second line. Twice open, twice close. What's the result? What do you think? The first twice should be a function name, and we have the function name over there, that's good. The second twice is an expression which should be an identifier, which should be either a primary name or a name introduced by variable, which is not in this example, meaning it's a free identifier error. How about this example? We defined a function named x, and on the next line we introduced a name x. Now we have two x's, function name and a name introduced by Val. Then we call function x open 7 close. What's the result? Is this program confused by using two x's? Not really, the semantics is clear. When we have ID open expression close, that ID this should be a function name, not a name introduced by Val, so that's going to be calling the function, which is an identity function, the result is going to be 7. How about this one? The identity function, so 3. How about this? This one is a bit different because now we have two definitions of functions named the same. What do you think? Can we use a function with two definitions of the same name? When we call this function f, which one is going to be called? This the question, well, when you call this function f, which one of these two is going to be called? In languages with overloading, there could be multiple definitions with the same name. Like Java and Scala and many other languages. But those multiple declarations, definitions of the same name should be different in the sense that when we call a function of the name, it should be clear that which one is being called, either like different number of parameters or different types of parameters. We can discuss that later if we want to, but until then, it's too much. It's an advanced feature, so we're not going to get into the detail. But in this F1 VAE implementation, we have this list of function definitions, and depending on our order of looking up the function definitions, it can remember that. We were scanning through the list of function definitions. The first encounter is going to be called. Is it the semantics that we want? It's up to you. If you don't like that semantics, you can change that. What's going to be the next example? The name of the function is f, but it's an identity function because the function body just returns the parameter so the result is going to be three. Final example, everything is f. We are defining a function f whose parameter name is f and the body is f. This body is going to be what? The parameter, so it's again the identity function and we are calling the function f with f. Again, this f is going to be the function because it's a function call. This one is going to be? Not a function, but some value of an identifier named f, which is undefined free identifier error. Hopefully, you understood the semantics now clearly. Then finally, function as values. First-order functions, functions are not values. First-class functions, functions are values. What does that mean? In first-order functions, we use the keyword D-E-F to define a function. That's a special thing, special different entity. But in first-class functions, functions are expressions. How do we construct a function? Just open curly brace, close curly brace, open close, and the parameter, arrow, [Korean] arrow arrow, and body expression. That's it. It's just like in mathematics, first-order function is like defining a function with the function name, parameter name, equals like this , and first-class functions, we just can create function expression with parameter name and body expression. This lambda dot is just a signal saying that this is a parameter and this is a body. This is just a function expression and we can give it a name, that simple. This is the concrete syntax of F1VAE that we are now familiar with and this is, the new language called FVAE. Previously, we emphasized that in F1VAE, functions are not values, so function is a different kind, that's why we had two different non-terminals for F1VAE but in FVAE, we have only one non-terminal, back to expr. There are two language expressions for making, introducing functions, and calling function. This question mark meaning that this is not yet correct. Let's make it correct. We can construct a function like this, look. As I said before, open, close, parameter name and arrow, body expression. This is going to be parameter, this is going to be body. Open, close, arrow, parameter name, and expression. This is a function. That's a function. How can we call that? If I want to call the function, what am I supposed to write here? This should be the syntax for this function call. [Korean] I know how to create a function, [Korean] but how can I use it? I can understand that we can construct, we can make function values like this, but how are we supposed to use it? This is an example. Let's look at some examples. How do we use it? There are at least two ways to do that. When you make a function expression, give it a name by using val just like other values. You used val a equals 3, val b equals 4, and then a plus b like this. Just like that, we can make val f is this function expression. Using that information, we can call the function f by using the name. Or we can just write the function expression right there in the function call. I'm calling this function. One more time, what did I say? After making a function expression like this, we can either give it a name and use the name or just write it over there, right there. So here we can use a name or an expression. Are you with me? So the syntax is going to be expr, expr, Expression 1, open, Expression 2, close. Expression 1 is just one of those expressions but when we interpret that Expression 1, the value should be function because it's a function call, and Expression 2, when we interpret that expression is going to be some value, which is going to be the value of the parameter. That simple. Let's see how we can do with that. In order to understand the semantics clearly, as usual, we're going to see some examples. This is the new language FVAE. What's the result? Ten is 10, 1 plus 2, three. We know all that because those all the syntax remain the same, then their semantics remains the same. y is a free identifier error just like that. The new information is what? This one, function expression. What's the value? It's going to have some value, but until then, let's assume that it's going to be just itself. When we evaluate this function expression, we'd better make a special value for that but in order to understand why let's assume that for now, its value is itself. Until we get the correct answer, correct implementation later, assume that it's just its value. The function expression itself is its value. Then what? Then the result is not always a number. You see 10, three, minus 1, nine, they're all numbers but now that functions are values, as I said multiple times, functions are values. We need to extend the value. Because functions are values now, we need to extend the definition of a value to include the function not only numbers. So the result of interp is now value, not only numbers but also includes functions. Then what's our example of function call? As we saw before, we can construct a function and give it a name and call it or we can just write the function expression and give it an argument. So if I say good, how about 1 plus 2 close, one, open two, close not 1 plus 2, one open two close. It's a function called syntax because the syntax is just e one, open, e two close. This one is syntactically correct. How about this one? Open plus one plus some function expression? It's also what? Open e plus e close syntactically correct, but semantically wrong. Are you with me? We have expressions that are syntactically correct. Parser takes them and produces correct abstract syntax. One plus function expression, number of when whatever expression close. They are syntactically correct. Parser does not reject them but semantically they do not meet anything. What do you mean by calling a number one? It's not a function. What do we mean by adding a number and a function? That's a philosophical question. There are going to be errors. That's the semantics of this language called FVAE. This is the previous language F1VAE abstract syntax. One more time there were trait Expr and Fdef, which is not a subtype of Expr and FVAE there's only Expr and we have function expression and function call. Function expression form takes a parameter name and body expression. Function call now takes two expressions. Do you see the difference? Previously in F1 VAE, function call, had our function name string with an argument expression. Previously in F1 VAE, function call took a string and an expression. Function should be called by its name. But in this new language f of VAE, function call takes two expressions. Function call doesn't need to be by name. It could be some names. Function call could be function expression in some arguments, or some name and some argument or even other. Another function call could be this E1. You should be able to understand this. You'd better write some concrete examples to do this. Yeah, I say del F of VAE and then function call E open, E close a two-point Degas, coupons and expression repeat Upsell identifier, stucco, junk on the irrigate jaw, para-function, Kirsty say, the cosine function capitalists T cell. In this new language, if a VAE, when you have this E open, E close, the first E could be Audition, which is going to be an error, which is not interesting. But that could be some name or function expression or yet another function call that producing our function value. If you doubt it, right, some examples and try that by yourself. That's going to help you understand this better. When we have this function expression, this is a parser thing, right? When we have this open x parameter arrow function body, we have this fun abstract syntax. When you have function call we make at all this is about parser. We're not going to talk about parsers anymore. Then let's implement this interpreter. This is the interpreter of F1 VAE. How about F of VAE? Many things are different, right? In F1 VAE, the result of the inter-function was a number. But in F1 VAE, the result of this inter-function is an integer, but not anymore in F of VAE. The result of this inter-function is x for y, because not only numbers for functions are also values. Instead of this number n, Now we just return E for numbers. Well, then how can you add the numbers? We need specific functions for adding and subtracting num expressions. We see that in a minute. Then function and function call are going to be two new important language constructs. Before talking about that, we are going to first define numAdd and numSub. Previously, when all the values are numbers, it was easy to implement interpreters because we are living with only number values: addition, subtraction, yeah, so simple. But now that expressions are values, when we have two expressions, we need to get the numbers there. This numAdd function takes two expressions and check pattern matching that with its actual F sticks syntax data. Hey, are you really Num to Nums? Then I know you have numbers in them, right? Then give me those numbers, I'm going to do that addition and put this Num-tech back to make it an expression. Or are you not two numbers? It's like number and function and functioning number or things like that. It's an error. I don't know how to add them. We need two numbers to add. Similarly, for subtraction, it takes two expressions and ask whether they are both the numbers. Otherwise, it's an error. Oh, are you two numbers? That's good. Give me real numbers. Then I'm going to do the subtraction and put this number back. Yeah, that's annoying because we have these integers inside num. We need to add and subtract with those integers and put num back to make this expert tie. If we have multiplication, division and more like that, and we're going to do this over and over again. Well, that's error prone. What do we want to do? Higher the function. This is why we are learning first-class functions. Yeah, higher the functions, meaning first-class functions in meaning functions are values. We can pass functions as arguments and produce functions as results. What did I just say? Let's look at this example. Now, this is a num function. In the previous slide, we talked about numAdd, numSub. We may want to have num multiply, num division like that. We do like to parameterize this functionality depending on the operation. It's not numAdd, numSub, but num operation. That operation is going to be an argument isn't it cool? Yeah, so it takes an operator as an argument, it produces a function as a result. It takes an operator and it's a function, which takes two expressions and match that with numbers. Then get those two integers inside nums and using those x and y two numbers, using this op, what is op? This parameter op. Wow, using this pest operators, addition, subtraction, whatever arithmetic operation we perform that on these two numbers, two integers and put this num tag back. These are when two expressions are two numbers. Otherwise it's an error just like that. One more time, this numOp takes another similar operator as an input and produces a function expression. The function expression takes two expressions like that and pattern matches their width to num expressions. Otherwise, it's an error. If two arguments are not expressions, not numbers, then it's going to be an error. If they're both numbers, then they're going to include integers. We're going to perform this arithmetic operator passed as an argument on that, and put this num back. This one is a library function to make numAdd and numSub. By using this num of functions, we can define numAdd and numSub by passing operator, isn't it cool? Yeah. If you do not understand this slide, it's more about Scala First-class functions. If you don't understand this, I recommend you to read the textbook. Thank you. Which of the following results in an error? Number 1, 10. Yeah, it's the result is 10, number 2 fail, x equals 7 and then x plus 2. The result is 9. Number 3, y is a free identifier error. Finally, number 4. It's a function expression. What's the result? The result is, itself. That's the result. Function is a value. The third one is a free identifier error, and the others results in corresponding value. It's important that function expression itself is a value in this language so far. In the next lecture, we are going to fix this firm. Thank you.