 Alright. Okay, so it's Wednesday. Today, Project 4 is due. And as people who are watching this later can't see, I'm sure there's going to be a lot of people watching this video later. There's not a ton of people in class, which, you know, scares me and worries me, but I don't know. There's nothing I can do about it, right? I mean, we talked about Project 4 on Monday, right? For the people who came to that, hopefully got something out of it for their projects. Questions before I get started? Maybe, if somebody else asks. Nobody has any questions? Everybody in this room has finished Project 3 or 4? Just an anonymous, in the back, extension. Why should you have an extension? Revisiting this topic? What? Oh, we can talk about it again. So, do you have any arguments for why you should have an extension? I wouldn't ask for it if it was like I just started last night, but I have been arguing it for like the last week and a half. That's good. Slowly going at it. That's good? Yeah. So I'm feeling extra good. It's not a very good argument. You came to class. Huh? Because you came to class. That's actually a better argument. I know this is a winner-take-all on the test cases. You get all of them to get the full credit? No, no, no. It's proportional. It is? Just like the last project, right? So yeah. If you're passing 50% of the test cases for that case is worth 10 points, then you get 5 points for that. That make sense? Yeah. So yeah, it's not all or nothing. Who's asking about the extra credit? Are you asking about extra credit? What? Are you asking about extra credit? No, no, no. Okay. So if you had 14 of 15 test cases, then you'd get whatever 14 out of 15 times 60 is, right? Four points. Four points? Yeah. Four points. That's 60? Okay. 14 out of 15? Yeah. 14 out of 15? Yeah. 14 divided by 15 is 10. Okay. 93% times 60 is 4 points. 4 points? Yeah. 4 points. Well, 95% is 56. 56 is 4 points. And a match is not a God again. You lose 4 points. Cool. Yeah. Any other questions, arguments, appeals? Yeah. I'll tell you a few things that I only had four people in office hours that I had right before here, right? I didn't come to the figures that were going to be packed. Yeah. That seems like a bad assumption. But even then, there were people standing, right? But we still had a good conceptual discussion about the project to help clear up some things, right? So that, to me, it's like, well, there's a big cry for an extension, but then nobody comes for help, right? Which means you all know what you're doing and should be able to finish by tonight. It doesn't always go to the TAs. Could you all go to the TAs? Yeah, most of them. Does they care about it seeing more than they should wait? Am I super scary? Is that what you're going to say? Is that a class before this? You got a class before that? I believe that. That's about, what about on Friday? I had like two people on Friday. Who goes to class on Friday? I hope nobody in this class, because we don't have class on Friday. Okay. Well, all right. So we'll get to this in a second, but I want to talk about something else. So anybody want to guess what this number is in relation to project three? How many people pass all the test cases in project three? I think that's not, we don't want to advertise that. I think that's not true. So we're talking project three, right? The last project. So I believe there was like, well I don't remember. I don't know if I can comment explicitly on grades, but... Is that the average grade? The average number of points. Also, a good guess. It was much higher, so project three grades are posted. Yeah. Did it turn anything in? Number of people that didn't turn anything in. Close. People that dropped the class. People that dropped the class. Actually, I think we're over that. I think we're 19 or 20 that have like officially dropped. I know. I am sad too. I am sad too. I wish everyone could stay. The number of submissions that are on time. The number of submissions that are on time. No, no, no. There's a lot of on-time submissions. And a lot of people, a good number of people had it 100% done before the deadline. The average number of submissions? The average number of submissions. No, that's a good guess. I like that. The number of people... I would actually be very good for this story. I actually don't know. The number of people that dropped the major grade in this class. Unfortunately, so this isn't... I don't know. We're kind of joking. We're having a good time. We're trying to keep our spirits up. I do work as a project. Unfortunately, this is the number of people who decided to cheat on project three. That isn't a lot of people, yes. And so I know there are some of you out there in this room who came to me when project three was due or after saying, you worked on it really, really hard. You spent hours, 20, 30 hours working on project three and you couldn't pass any of the test cases. So I want to say first off, hats off to you for fighting a good fight and taking the zero. Failure always sucks, right? It's never fun, but you learn from it and you pick up and you keep going, right? So kind of in lieu of this number, I think I'm happy to give a two-day extension on project four for those of you who are still in the class. Still... What was that? Thank you. Thank you so much. Don't thank me. Thank yourselves for being very ethical and vigilant and continuing to work really hard in this class. I do really appreciate it. And if you still have questions on Friday, come to office hours. Yes. Leave your job, play your job. No, I'm just kidding. Okay. Yes. So after those 13 FTs... They had... We applied the course policy, so does that remember what it says in the syllabus? They also dropped their class. They what? They also dropped their class. I can't really comment. I don't know. Exactly. Yeah. Can I take you to dinner with us? I think that would be like a conflict of interest thing. No. So the penalty for academic integrity violations is zero on project three, which is definitely fair. But to me, that's not fair. It's not fair to everyone else who got a zero and worked really hard. So they also get a full letter grade reduction in the class. So if they end up with a B, they get a C. Right? So... And you also get bad stuff happening. You can't ever apply to this... You're not going to report it? No, no. And they get reported to the dean's office where they keep a list. So now that this happens again, there's very serious consequences. That's pretty serious in person. It is very serious. I agree. But there's even more serious dean-wide, college-wide sections that get imposed. But that's kind of above me. Yeah. So are these people just talking code straight from the person? So there's a couple cases. Yeah, there are cases where the code was very identical. So that's very easy. There are cases where they found somebody's code that was posted from last semester. And I believe I mentioned this on the very first day. We run all of your code against all the previous year's code back to the dawn of time to look for similarities. So when it pops up that, hey, your code's very similar to a student from last semester. And then I Google for function names in there and that pops up a GitHub repository from this student from last semester. It's a pretty clear indication of what happened. So there's another reason why, so whatever happens to that student is out of my hands because that's not my student. But it could be very possible that that professor decides to prosecute that student for academic integrity violations. Just like it's in our syllabus, right, that you can't post this material online, your assignments. Otherwise, there's going to be very important consequences. So please don't do that because I don't want to have to deal with it. But I will deal with it if it comes up. Any other questions? Any other, yeah? So those of us that took the zero, are they cheap? Maybe. That's, yeah, you have the extension, right? We'll talk about that. I want to see kind of what happens. So I know the drop-debt, well, I'm not completely oblivious, right? I know the drop-debt line is the fourth with the withdrawal deadline, right? So before that, I will see where the grades of the people who are left are and I'll see if things need to happen to kind of deal with that, yeah. We'll find something that's fair, yeah. I believe so. Okay, Tommy, I took a zero, but I listed it as a blank. I don't. That may be something weird with the TA. Or it could be because you didn't have a thing to match it in. But that's for free with YouTube, admit that. Perfect. Yeah, it's probably because of this thing going on. I don't know yet. Yeah? Yes. It'll be up, you know, after this one's done pretty much. I wanted to give you time to focus on this project before worrying about other projects. So it'll definitely be released sometime next weekend. Well, we have, like, two or three weeks to work on it. I think you'll have, like, four weeks. Yeah, it's a long time. So. I've heard this one with the hardest. I've heard the three is the hardest. Yeah. Three is the scariest to get started on. Yes. I don't think it was as hard as the last one. I think it's in project three. We're going to need code for project three for project four. Nope. But just like before, they're all three separate categories. On the syllabus, it says that there are six homework assignments. With the calendars, there's five. Yes, I switched it. So there's five homework assignments. So it doesn't match up. It can potentially be a bonus homework or a make-up homework. I haven't 100% decided. Once again, it depends kind of on the grades, yeah. Can you meet with me before Friday? Can you meet with me before Friday? Maybe. You can send me an email to try and schedule an appointment. There's also motion has office hours tomorrow, too. And Cy has office hours directly after this class. And there's the mailing list. You guys are helping each other out. I really appreciate that. Yeah. We're going to have a midterm. Do you want to think about that now? Close some projects because they're project four. Anything else? They say it like it wasn't really nice. Yeah. Cy has it. You're going to make a point with Cy. He has all the midterms. He'll be able to email. Any of your project four questions? We can spend a little bit of time going over that. I'm happy to do that. Okay. So, what is a type one error in our project four? We're just going to declare it as a variable. Type redeclared as a variable. Type redeclared as a variable. So what does that mean? Where are all the places in our program that we can declare types? Type section. And the bar section. Type section. So explicitly declared in the type section, explicitly declared in the bar section. So, if I have something like this, it's really fine. So, I have this line in my type declaration. What types of declare here? Let's go to you. What types of declare here? Okay. So, if in my variable declaration section, I have something that looks like this. Is that a... Is this a type one error? No. I'm declaring a variable called x that has type b. What if it's the other way around? Yeah. Right. So, not double declaration, right? Type one error. So here, I've declared b as a type. But I'm declaring a variable called b. Right? Definitely type one error. What about if I had... Say we can remove this line and remove our type section. And I declare a variable b as type a. Is this valid? Yes. And I do this. What kind of error is that? What was that? Yeah. Type one error. Why is it type one? Because a is supposed to be a variable that you have on top of a variable. Yeah. So, even though it's not in the explicit type section, right? We've declared a type called a. And here, we're trying to use that type a as a variable. Okay. What if we have this? What if I have a... So, what am I declaring on this line? What's the explicit type of a and the explicit type of b? Right. So, I'm declaring a type b and its type is type a. So, I've declared, in essence, two types. Type b and type a. So then, what? Is this line... Oops. Is this line valid? No. What kind of error is it? Type one error. Type one error. Right? Because I'm trying to declare a variable called a whether the a already exists as a type. Yeah. It doesn't really declare it, right? It is... Essentially, this line is defining that a b and d are type a. Right? That's what this line says. Just like if I said e and f are type int. Right? This says that e and f are type int. There's nothing in my language that says that what's on the right-hand side has to already be declared. Right? And that's why we have implicit types. Yeah. What do you mean? Are you asking me if it doesn't matter if you write valid good code? It doesn't matter to the test cases. It does not. So then, I think I answered your question. Any other questions? Project four? Is we're going to get some material, huh? We've got to learn about pass-by value. Yeah. So, any variable that makes its person clear to your body, you know you have like a t0, t1. That's not considered implicit declaration. So, let's think about this. What do we have? We don't have a variable section, we have this. So what kind of area is this? Type 1, right? So here I'm trying to declare a variable, or use a variable that's a type. It's definitely a type 1 error. Do I have one with your question? So this was tangential, right? Like, if it was k, right? Is that not a, well, not exactly, maybe like, the k is type of a zero. Wouldn't that be like implicit? So, yeah, it kind of depends on how you do it. So, we're talking about this in office hours. So, here we have a variable k that's implicitly declared. So the question is, do we ever declare types in the body? No. No? When I have this variable k here, well, not that. So I have the variable k here, right? So, when I see this ID, what's the first thing I do? Well, also, if you want to check a type 1 error, it's already looked first. Look at the type list, see if it's already the type. Then you look for it in the variable list. If it doesn't exist in either of those, then what do you do? So it's a new variable, right? So you're creating an implicit variable, so you have to add it to your variable list. But what type does this variable have? But if we just look at this k in isolation, right, just this ID, what type would it have? Yeah. It'd be an unknown and implicit type. So the question is, well, let's say I have, I don't think we can do this in our language, but let's say we can, right? These are expressions of this variable, right? So, we're saying, okay, k has some new implicit type. Then what do I do for j? What kind of type does j have? What was that? So why its own implicit type? Are they the same type? No, we have nothing that constrains them to be the same type, right? So that's what you have to do. Essentially, you can think of an implicit variable as creating its own unique type. Every time you see a new implicit variable, you should create a unique type for that variable. And then the constraints of the type system will tell you what that is. So in this case, if we have k as equal to 10.0, what would the type of k end up being? Real, it would be a real, right? Because this can shrink in the type system. So some of you in my office hours may be a good point that in the Project 4 description, there's the lines of, there's like seven or eight bullet points of all the things that have to be constrained in the type system. And this person made the comment that that is their Bible. So this is what they look at, because those rules define exactly what the type is on the left. So that's the rule that tells us that, hey, k better be a real. And if I can't, because I've declared, let's say, up here a variable type k, k as an int or a string, I'm going to say, I'm going to say, I'm going to say, I'm going to say, I'm going to say, I'm going to say, I'm going to say, an int or a string, right? This would be a type error here. Right? So it needs to be a primitive to cause a type error. Exactly. That's one of the things you can think about. If you ever have to, you think primitive or built-in, right? If you ever have two types, they give you the constraint that they're the same and they are both built-in types and you know that that's definitely an error. But what if k had the type e? Same thing. So why the same thing? Yeah, we know e is an int, right? And it doesn't matter how long this chain is, right? We can have e and f for both a's and we can have a up here is a string, right? So we know that type a is a string, e and f are both type a's. So all these are constraints, right? To the type system. So this is defining that type a is a constraint. The type of a has to be a string. This is defining the constraints that e, f and a both are all the same type. And this constraint says that variable, the type of variable k is the type of e. And then what does this constraint say? That the type of k is a real, right? That's what this constraint says. So long, but we can't solve that, right? That can't be constraint. So that would be a type a. Any other questions? We'll probably do it in five or six more minutes. Yeah. I want to look at one of the test cases that we do, given test case five. And the very last line has implicitly declared variable p, y, or q, y. So p, y has implicitly declared a new variable. q, y wasn't declared more even. It's supposed to pass. So you take p, y. So now it's like, hey, we have a variable of type unknown. Not type unknown, right? The type is unknown, but it's a new type. It's a new type you've never seen before. So that's the big difference, right? Otherwise, if you're saying that it's just you have an unknown type, then any implicit variable you say has that unknown type, then implicitly you're saying that they all have the same type. It's not bad, right? So be careful about that. Yes. So I guess we're so q, y is something we also don't know. Right, it's a new type. So in essence, what are these types in this type section? What is this doing? What does this allow the programmer to do? What was that? Explicit types. Explicit types? Yeah. We talked kind of about it. It's like an element of type system, right? So how many types do we get the programmers? Five. Five. We define them five for them, right? But then we also give them the ability to do in this type section. Yeah, they can make their own types. They can define their own types, right? So these are constructing new types. Here we have a new type e, a, that doesn't only exist in this program. It doesn't exist outside of that. And it's the same as the type string. So just the same thing in here. Exactly. So when we see implicit variable p, y, I know, okay, now I have a new variable p, y, and I know it has some new type. I don't know what that type is. You can give it an internal name, whatever you want. As long as it doesn't conflict, obviously, right? Q, y, and q, y also has a new... Exactly. So that passes because they're both... Exactly. And then what do the constraints say after this? So what is this assignment operation due to the types of p, y, and q, y? I think you're sensitive, yes. Yeah, constraints that, but they have to be the same. That's good. Exactly. So if that way is later, I have this type there. Bam. Yeah. So what if p, y, and q, y... It was like this? Yeah. Better type it around the line. Than the type around right here? Yeah. Yeah, exactly. So here you create a new variable p, y, you give it an implicit type, a new implicit type, and then you say, oh, this constraint means that that type on the left is the same as whatever the type is on the right. The type on the right is an n, so I know the type of p, y must be an n. Then you get to this line, the same thing with the real and the q, y's type. Then you get to this line, you're saying, hey, p, y, the type of p, y has to be the same as the type of q, y. So can we make those the same? No, because they're two different built-in. One is an nth and one is a real, so those don't matter. Those are structurally, structurally quality, they're structurally different. Yeah. So just to be clear. We should be like, a equals to 10, that means one error. So if we were to do where, at the top? Yeah. Like this? Yeah. Yeah. So why is it a type, so why is this type one error? Yeah, so we're using a type as a variable, which is definitely, we should not be doing it. Yeah. How do you guys end up? Questions on that? We can make sure that this is all dialed in. Expression, factor, expression. I think it's the other way. Expression goes to factor, it goes to term, and I think a term can then have more expressions or maybe it's the other way around. Yeah. Expression goes to term. Ah, okay. Expression goes to term, term goes to factor, factor can then go back to expression with brackets or with parentheses. So what is the actual data structure in syntax that h looked like? Are there any factors or terms in there? So why? Maybe you want to tell us why? Yeah. Wait, I don't think I missed the question. Is it because they're all expression nodes? In syntax.h they're all expression nodes, or there's only expression nodes. Right. But in the grammar, there's expressions, there's factors, and there's terms. So why? Why is that? Yeah. Is it order of operations? Yeah. It's in order, it's pretty much in the grammar that ensures the order of operations is how we want it to be. But when we're talking about the tree, order of operations just matters to create the parse tree in the correct order. But they're still all expressions. You can consider them as expressions, right? So yeah. Cool. Yeah. I mentioned that the condition would be... Yes. So for a wider statement to execute correctly, it's fantastically... So the question is on conditions? Yeah. Okay. So here I have, I think it's like while... So what is the condition? There's two cases. What is the condition? Either ID. Is it either what? Either ID or primary... Right, so it's either an ID. So in this case it could be K. Right. So while K, and then I think it's just something like this, right? And then I can have... How does it do while go? Something like this. Do... I would say K less than B. Something like that, right? So these are... And I think a semicolon at the end? Yeah. All right. So what's the constraint data type system about conditions? That should be a Boolean. That should be a Boolean, exactly. So what's the type of this condition right now? E. Right? So we know K. We know K is a variable that's defined. And what's the type of K? E. E. Exactly. So then now what does our type system say about the constraints on type E? E is an A. E is an A. A is a string. And so it's going to string be a Boolean? No. No. So we can't do that. So this is a type error. If this was instead of... Boolean like that, or just Boolean? Boolean. Boolean. Boolean. Cool? Okay. If we add it like this, does this type check? Yes. Yeah. Because whatever the condition is, it has to be a Boolean, right? All right. Let's look at this one. Okay. So this is the condition of this do-while statement, right? So it's of the form ID real-off ID. So what do we know about the constraints of a relational operator or the real-off? Exactly. That what have to be the same? Have to be the same? Same type. Okay. So left operand and right operand have to be the same type. But what else do we know about the constraints of a relational operator? That it returns a Boolean, right? So therefore we know if this case... Okay. The relational operator always returns a Boolean. So therefore that type matches, right? We don't have to worry about this returning Boolean or not. But what do we have to make sure about the types of the primaries on the left operand and the right operand? That they're the same. That they're the same. Exactly. Even though we haven't seen variables A and B. So what do we do when we haven't seen a variable A? We have... Yeah, exactly. So we see variable A. We've never seen it before. So we create some new implicit type for variable A. And then when we look at variable B, or when we look at a B, which is an ID, we see A. B is something we've never seen before. Create a new implicit type for it. And then our constraints of the conditions say that what about the type A and type B? They're the same. They must be the same. Got to be the same. So those type checks, right? This is fine. We don't know what those types are. But we know that they are the same and they can be the same, so type checks correctly. Let's go back to our discussions about parameter passing. This is really fun too. All right. Where are we? Okay. So we are looking at an example of pass-by value function parameter passing semantics that we've talked about in so far that we've printed to use in most programming languages. So I'll just briefly go through this. In our main method, we're declaring a local variable Y. We're passing that to some function test. We're printing out the value of Y and then we're returning Y. In test, we are incrementing the formal parameter that is passed in by 5. We're printing that out. And so we looked and we saw that, okay, it's actually printing out the values 9 and 4. And then if we related this back to our box circle diagrams, right? So we have box circle of Y. That's this local variable. We have box circle of X. And when we're calling from main to test, the semantics, the exact semantics of pass-by value is take the value that's in the location associated with the actual parameter, which in this case is 4. Copy that value into the location associated with the formal parameter here. So here in this case is X, so 4 gets copied. We add it 5 to it. We get 9. We print out 9. And then that returns. That gets automatically de-allocated. And then we keep going. Questions on pass-by value? Okay. So the other major way that you can do, you can have a semantics for variable passing is pass-by reference. Here with pass-by reference, the big difference is that the formal parameters are bound to the location associated with the actual parameters. So here we can actually, so here we'll see. So this means that our actual parameters that we're calling must be L values. If we're trying to do pass-by value, or pass-by reference, and we try to pass a value in there that doesn't have a location associated with it, we can't bind our formal parameter to that location. This goes back to every remember the difference between L values and R values. What's an R value? Cool. Back of the head, it gets very edgy. Yeah. As far as the box circle is concerned, how I do this again? I do that with the technical circle. The R value is either a value or a location that has a value associated with it. Yeah. You can use those as an R value. In other words, an L value has a location. So the box circle has a box. Right? Just if you have the constant 10, right? That has no location associated with it, so it's not an L value. The other way to think about it is anything that can be on the left side of an assignment operator. Right at the left. Okay. So let's look at an example of this. Plus, plus actually supports a pass-by reference that you as a programmer can specify on certain parameters of your function. So here are various, I think, pretty much identical examples. So here you're declaring a global variable X. In our main function, we're declaring a local variable Y. We pass Y to test. We print out the value of Y and we return Y. So is this any different? No. A previous example? No. I hope not, but it shouldn't be. So what we do in C++ to say, hey, this parameter we want to pass by reference, we include the ampersand in its signature. So we have the type ampersand in X. So this is just another way for us to, as programmers, specify more metadata about this parameter, this function parameter. And then in the body, we have the same thing. So we're taking X, we're adding five to it, and then we're returning, we're printing out the value of X. So which, is this X going to be bound to this global X? No? What determines that? You're referencing the X in the scope of test. Scope, yeah, scope, right? So the scope, the global X has global scope from where it's declared all the way to the end of the file. But this X that's a parameter in the function test, a formal parameter, that has scope in that function X. So what does it do to the global X? Your whisper? Does it add five to the address? I don't know, what does it do to it, I'm talking scopes here. Does it ignore it? Does it do what? Does it ignore it? It does ignore it, but there's a specific term for it. Yeah, so shadowing it exactly like that. So this X, that's a parameter because its scope is closer you can think about to test. So you look for scope resolution inside out, So if you find it in your local scope and use that value, otherwise then you go to global scope or you go to the next scope after that. Yeah, but that doesn't make sense though. It doesn't make sense though? Yeah, it doesn't make sense to say x is equal to x plus 5 in that specific instance. Why? Because you can't, that's an address of x. That's being passed and isn't happening. Not an address of x. We're just saying that this is, we want pass by reference semantics for this specific parameter x. This is how you do it. And it's semantically similar to address of, which is probably why they chose this symbol. But it's not the same thing. Yeah, this is a way for us to declare in the function, hey this first parameter of this function test is going to be pass by reference. So that way the compiler knows when it calls it and then that way the programmer knows when they call this function. Yeah. When would it be good to use that? Because it's the same as passengers y, right? Is it the same thing as passing in this function? Or at least have the index without the standard. So that's actually a good point. So is this code going to execute differently or the same as the last example? What is this code going to output? What was it? Nine nine. Nine nine, why nine nine? Because in the function it adds five to the value and prints it and then when you get back, since we passed y by reference it actually changes the value of y. Right, so here we have pass by reference semantics. So here we're going to bind, when we invoke this function test, you can think about we're going to bind the name x to the location that we passed in. So what's the location that we passed in? Y. Y, exactly. So when we add five to x, what are we really changing? Exactly, the value of y. But when you're passing in y there, how are you passing in the location specified with y? It's expecting a reference to the location of y that you're sending in y itself. It's not expecting a, we're passing, are we passing, so the question is are we passing in L values to test? The function test? No. No? Maybe clarifying. Does y have a location, does the expression y have a location associated with it? Yes. Yeah. Right, it does. So when would you use an ampersand in that specific scenario? So remember the ampersand is just syntax to tell the compiler for this parameter I want to use pass by reference semantics, not pass by value. So in C++ you can choose between when it makes sense to you. So this ampersand is not the address of operator. So let's look through, so we kind of talked about it, so let's, where are we at? So this specifically is this ampersand character. So okay, let's compile this so you can take this program and compile it with D++. And you can run it, so what's the first thing it's going to output? Nine, and which function? Test. Test. Yeah, so function test is going to output nine, which is the same. And then when it returns, what's the value of y? What's y going to be? Nine. Nine. Right, exactly. So this is the way you think about it. So we have our box circle diagrams, right? So here we have the name y is associated, is bound to the location that has some value in it, right? And so we've done this, right? So this y is a local variable. We know exactly how to write the box circle diagram for it, and we know when it gets deallocated. Okay, so what's the value in y? Nine. Four. Yeah, right here, four, before we call test. Okay, so this is where, so everything up to this point is the same, right? But because this is passed by reference semantics, the formal parameter x, does x have a location bound to it that is separate like we have for y? Nine. No, exactly no. x does not have any location. So what happens when I invoke test, when I call test? X gets bound to one for the location. X is going to get bound to the location associated with y, right? So what's going to happen is when this function gets called, x, we're going to draw a line from x to the box y. So this is the binding of the formal parameter x to this location that is associated with y. So now when I add five to x, what happens? Yeah, I add five, so in this, right, the semantics here are the same. So I take the value in the location associated with x, what's the value in the location associated with x? Four. Four. I add five to it, what's that? Nine. Nine? One of you? Very good at nine. It's not even hex math anymore, it's regular decimal math. All right, it would also still work in hex math, I wasn't going to say that. All right, so let me take nine and what do the assignment semantics here tell us to do? Does anybody want to go with the super verbose assignment semantics? This is a good review for that midterm that we've just got really reminded from that's coming up soon. Yes, not in terms of the assembly, in terms of the locations associated with blah, blah, blah, this is not at all like the semantic. So here, five is an R ideal. So it's added to the location associated with x, that is four. is for times the store the value associated with the solution one and prime x. Not point of value, but yeah, that's about it. So that computation happens, right? 4 plus 5, then that result is an r value, right? 9 is an r value. And so we're storing that value in the location associated with the left-hand side, which is x. So where's the location associated with x? 1. Totally 1 box here. Yeah, it's pretty easy, right? It's this box here. So then we're going to put 9 there. And then what happens when main returns? Or when, sorry, when test returns? Yeah, x just disappears, right? So the name goes away. But we never create a location for x, so we don't reallocate that. And so now when we print out the value of y, we print out. Yeah, exactly. Because that's what's in that box associated with y. Yeah? So in main, what if you printed x? In main, what if I printed x? What would happen if I printed x in main? What was it? It's not initialized. It's not initialized, yeah. So it'd be whatever. Because in main, what does x refer to? Scoping rules. The global x. Did I ever set the global x? No, so it's going to be whatever garbage happens to be in there. It's going to print out. Yeah? They won't let you pass just 10 in test, right? You have to pass everything. Correct. Why would it not allow you to pass 10 in per test? There's no location. Yeah, exactly. 10 is on an L value. There's no location associated with the value 10. So yeah, I can't pass 10 in per test here. That'd be a good example. Just the tricky thing to put on a midterm, maybe. Do it. Yeah? So if you do y, you need to test as value. It does basically the same thing. So say that again. So let's take the first thing just to make sure we're talking the same thing. So can I take into test, can I pass in the address of y? Yeah, can you make a pointer to y and then pass that? So can I do that? Can I change this by calling test and putting in the address of operator before y? Would that be the same as passing 10? Huh? Would that be the same as passing a rate of play code? Would it be the same as passing R value? What is the address of operator return? Address. It's actually a good test for me. I can't remember if it turns both R and L values. I think just R values. But what's the problem? So what's the type? So let's go to type systems. So what's the type of the address of y? Instar. Instar, it's a pointer to an integer. Does a pointer to an integer match an int x or int? No, right? We can't do that. So I'm pretty sure of that example. So that would first not type check. So then I think there's a second part to your question. Maybe you're trying to get at it. Yeah, if you changed int x to just int star x. Yeah, so does everybody see that? So if I change, so if we go back, we have to go back to pass by value semantics, right? So I guess you don't have to. But if we went back to pass by value semantics and we said, OK, the parameter to test is an int pointer, an int star. And then here we say star x is equal to star x plus 5. And then I print out star x. And here, can I pass in y? Why not? It's not an int star, right? Yeah, the types don't match. So I'd have to do what to y? Ampersand. Ampersand, yeah, I'd have to take the address of y. And then would that be functionally equivalent to this example? Yeah, so you could think that, you know, so there's a couple different ways to think about it, right? There's thinking about it from looking at the language perspective and thinking about the box circle diagrams, right? Because this is what the semantics presented to you from the compiler, the specific compiler says. But then there's how the compiler actually implements it underneath. So under the hood, that's how it implements this. Is it would actually just take the address of operator of whatever you pass in, and then it would change this to basically a pointer and it would dereference it all to the place, right? You could just easily do that. So it's one of these things where you can hide that implementation detail from the programmer. And you can just say, hey, these are the different ways you can pass parameters into a function. So that's still considered pass by reference as well, if you work with the ampersands of pointers. So if I have int star x here, is this pass by value or pass by reference? Value. That's not a value. Value, why? So you're passing a pointer in, but what's a pointer? What's the value inside of a pointer? The address, right? It's the address of whatever it's pointing to. So with a pass by value semantics, you just take that value from your actual parameter and copy it into the formal parameter. So there are two separate locations that they point to the same address. Yeah? Why don't you have to dereference x inside of test? Why don't you have to dereference x inside of test? Is x a pointer inside test? Is x a pointer, though? What's the type of x? It's an int, yeah, exactly. So that's what I found out with x. The compiler is hiding the implementation details from you, the programmer. So as a programmer, all I need to know is I pass in a type x in here. And I also need to know it's passed by reference because this function could change that value that I pass in. But when I use this, this is what the compiler says. So the reason is because C plus plus says so, if you don't have to. This is also valid for C, not just C plus plus. It's not valid for C. This is not valid for C, though. That's why I used C plus plus. That's why I was being misplaced. So wait, just a second. I know this isn't going to decide, but if it was C, you have to pass with an int pointer. If it's C and you wanted this functionality, you would have to pass with pointers, yes. So in C, what is pass by reference and pass by value? C does not have pass by reference to mantis. Everything is pass by value. So this is the difference, right? So this is about how languages evolve, right? So people say, OK, let's just do pass by value and then somebody comes up with a new thing and says, hey, what if we did pass by reference? That would be cool. And they implement it in the language and they give that power to you, the programmer, so you can decide through your functions if you want to pass by value, pass by reference. So it could simplify things, right? Instead of passing pointers all over the place, if you're just going to use it to change that value, then maybe pass by reference makes sense from a semantic perspective. So yeah, why might you want to use this or why might this be useful? I think I would be. So you don't have to dereference it inside the code. It kind of tests a little bit more self-contained. Yeah. So you pass by reference and then you take the reference of 3.x to a different place. You mean why? I think no. I don't know though. You'd have to exercise. I think you could probably do it by messing with the type system, but I think the type system wouldn't allow you to do that. Yeah, I don't know 100%. That'd be interesting. You should check and see what you could do. So I know what's it. So can I pass in and pass an int star by reference? Why not? What's an int star? State point. It's just a type. Yeah, it's just a type. It's just a pointer. It's just a box with a value in it, right? So I can pass that in by reference. And what would happen is that would be x and y would point to the same value and whatever was in there would be an address, right? So if we assigned it to x, we could actually change where y points do, which is, yeah. So in that case, you're going to have to do a star, right? Yes, in the type. The type here would be int star and percent x. I'm not sure exactly where each of them go, which is syntactically valid, but somewhere. Then also in the function, you'd have to do star x. If you want to get where x points to, yes. But you could change what the actual parameter points to by copying a value into x. Because x and y refer to the same location. Like we did an example of this, yeah. I'm not sure if I quite got that. So you're saying you can interchange the random sentence, why do you know if it's actually the same thing? Not exactly. So two different concepts. Two different concepts. So yes, if you just have class by value semantics, you can simulate it, pass by reference. So in here, I would pass in pointer to int star x. And here, I would change all these x's to star x, right? So here, we're in our function, we're passing in pointers to a medical occasion. And so the function can dereference that, change that value, and then when we return, we see that same change value, that's one thing. The other thing is, we can pass. So here, we're passing in an integer, which is a type. It stars just another type. So we can pass a pointer by reference. And then you just do the same thing. So whatever's in this value would be an address. And we could change that by assigning it to x. And we could get what x and y point to by dereferencing x. These are good at finding midterm questions. All right, so why is this useful? Update more than one type. Do we need to update more than one type? So because with a function, if you know the return one type, and then you want to do an update more than one type, you, it's really easy to pass by reference and update both of those types in that function. Right, so how many values, how many types I feel like that? So how many types can you return from a function? One. What happens if you really want to return two things? Yeah, you either have to put them in a struct, which maybe that struct is only used for this specific function, so it'd be really annoying to make a struct. What if there's no real name for that struct? It just happens to be, you know, maybe those two data points aren't really related, but the function computes them anyways as a library or something, right? So here you can have parameters that essentially get the result of whatever function call you're calling. You could call them out-parameters too, right? So there's some parameters that are inputs to your function and some parameters that are outputs to your function. This is really just getting around the fact that you can't return more than one value. So in a language like Python, where you can return more than one value, which is essentially a tuple, right, this kind of goes away. You don't really have this problem so much. What else? So returning multiple values is another thing. There's another kind of key use. Yeah? What doesn't have to do with global? Yeah, so that's kind of the fact at another point, right? So the other way, instead of passing something in, you have that function reference to global variable, but now you're tied to that global variable, right? So if somebody else ever changes it, you have all kinds of nonsense. Yeah, what about, there's one other reason, I think. Save space. Save space? In what sense? Yeah, you don't have to make copies of very large objects. That could be. You're passing in essentially a pointer and down. You're not creating new locations. That's pretty good. Yeah. Is it safer? Is it safer? Is it safer to see when? Interesting. I don't know, actually. I think I'd say, I'd say it's a little safer. Is it safer to see when? Yeah, because, yeah, because the compiler is basically making sure that you're de-referencing it correctly, yeah. Especially for this one case, right, where you want to make sure you get that return value. In this case, if you're only ever going to de-reference it, then that's fine. And it's explicit, sorry. It's explicit, so it's in the type, right? So anybody who uses this function knows. Whereas if you have a function that takes in an int star, is the function going to assign to that or change it? You don't know, right? It could, it could not. What about, how about if you want to create a pointer or allocate some memory, right? So how do you allocate memory on the heap? Yeah, let's think C for a little bit. So malloc, right? So what do you pass in the malloc? Size, which is, it's a size t. What does that number in that size t represent? How much memory of what units? Vites. Vites, yeah, the number of bytes that you want from that to be created, right? And what does malloc return? An address, yeah, it returns the address, right? So how would you, let's say you wanted a function that allocated memory, right? That allocated something, right? How would you, how would you have to return that pointer? You can't, so there's, I'm kind of losing my train of thought. But the point is that when you're mallocing memory, you get a pointer, right? And so you need to return that address back to that function that called you. So one of the ways you could do that is with call by reference rather than using it as a return value. Okay, so this looks crazy, right? Kind of, a weird maybe, unintuitive? I don't know. This is a better morning experience. What we're gonna get to next is really crazy, which is why it's super funny. Okay, so now, so this is what happens when people start thinking about cool language features. Like, oh yeah, we have pass by value, pass by reference. And then they're like, what if we took it even further? So this is a concept they call, we call pass by name. So what this is, the way you think, so it's actually pretty simple conceptually to think about, and maybe, I don't know, it's really hard for me to remember my first programming experience, but maybe you kind of thought about parameters and functions like this. So what we're gonna define the semantics of this is that the formal parameters are replaced by the text of the actual parameters everywhere in the function of the formal parameters occur. So what does that mean? Let me like, decode this in the more lonely language. Yeah. So if you would pass in, if you call a function, what would you do? Yeah, so, more simply, it's like, it's simpler. Well, it's over here, yeah, it's simple. Yes, it's the, yeah, if you wanna think of it like that, it's the runtime equivalent of a power define. So, before that function, foo is executed. Let's say it has parameter x, like our sample, right? When that function's executed with a new value y, it's like you replace the text everywhere you see an x, you replace it with y, and then you execute. Does that seem crazy? Yeah, yes. But it seems kind of intuitive, right? I mean, you call a function, you replace, you replace it all. I mean, maybe not if you're thinking about how computers actually work, but if you think about like the function call level, yeah, that's a valid way to think about it. So, let's look at our example again now with pass by name semantics. What if it's still in C? Still in C, so, does C have pass by name semantics? No, it only has pass by value. Does C plus plus? No, so, this is more of a historical kind of thing, but it helps you to think about these are just different ways of defining semantics. So a little bit of history, like the pass by name was created in, I think, Algol 60, which is one of the precursors to C. So they thought like, oh, this is a cool idea, you know, back in the 60s when they were creating this programming, we just left and right. They're like, oh, this is a cool idea. It's a very simple semantics, right? These semantics, you could explain this to kind of a lot of people, right? This is pretty, just text replace, right? You wanna know what that function does when it's invoked? Look at the parameters and text replace it. The formal parameters with the actual parameters. It's pretty simple. Turns out to have a lot of weird corner cases and it's really weird to implement, too. So, look at our example. We have test, we have x is equal to x of five, we have x, okay, same function. So, same function, so it's clearly C code, but we're saying this is C code that has pass by name semantics, right? So, this would be like if I gave you code like this on a midterm and I said, well, that's what this program be with call by value semantics, part one. Part two, call by reference semantics. Part three, call by name semantics. I think you'd be able to answer that. Okay, so we're gonna do textual replacement. So, when test is called in the vote, what is the essence of the semantics and what's gonna happen? So, what I said, yeah. Everywhere in test where there's an x that's in place with y. Yeah, so everywhere there's an x in test where we're gonna replace it with y. There's also a thing of this is kind of a poor man's inlining, right? You're kind of just inlining that function in there by just doing textual replacement, yeah. Does it also send the value of y in, too? Because otherwise that function can't see y or anything. So, text replacement, but yeah, so the scope rules get a little wonky. So, this has the scope of whatever, the actual parameters have the scope of wherever they are called. And you can think of they can access back into this scope. So you can kind of think of it as maybe, well, let's see how I do it that way, but you can kind of think of replacing this called the text with these lines. Okay. Right, like inline replacement. But then you have to worry about if there's local variables, all that kind of stuff, that's one way to think about it. Yeah, so I think about it like, okay, we're kind of making a new copy of this function test, and we're gonna replace all those x's with y's, and these y's all referred to this y, right? We know because, and so, we know that exactly when we invoke the test, we know what the scope of this y is, actually a compile time, right? We know what this y refers to. So we just replace that all in there. So we compile it with a fake, don't try to compile this, or it will compile, it's only gonna do the same thing. If we fake ran this, what would our output be? Nine and nine, y. Yeah, because everything is y, right? All of the assignments in that function refer to the variable y, right? So, I didn't draw a box circle diagram because there's only one box of one circle. It's the variable y, there is no x, x doesn't even exist. Okay, x does exist, so it goes with variable. In the function test, when we invoke it with the actual parameter y, it does not exist in that function test. Good point. Questions? Yeah? How would we be able to pass the global variable x test? Would we be able to pass the global variable x? Yes, yeah, we absolutely would because x is in the scope here of main, right? So when we pass that in, we do textual replacement x, but we also make sure that those x's all reference that same x that we passed in. Okay, so let's look at it. So is this any different from any other semantics? Yes? Oh, maybe? Yeah? So there's two different functions called tasks then? No, but I think, so this is how, so when you think about textual replacement, right? This is where I think when we invoke it, to think through the semantics, we consider that we're executing a new function test where we replace all the x's with y's because this will help us understand, right? So this is why this y changes, right? Because the y in test is referring to that one, yeah. Also think of it as just doing a replacement, taking test y out and putting it in there and then putting it all in place. That's actually why they thought of doing it like this because they thought it would lead to really cool inlining optimizations. So that's the other thing, you could replace this test y call with these two lines, right, and it's exactly the same, yeah. That's my reference. That is the question. Is there an effective difference between this and pass by reference, yeah. Could you have an issue if the function had a local variable already called y? Yeah, so that's a very good point. So what if the function has a local variable y? I think the scopes, because actually I don't think, okay, good. So if you have a local scope, like a block inside the function, you could define a new variable y. But I think the compiler would be able to tell the difference between the local y and the parameter y, so it would be the same in that sense. Yeah. Did you pass in a function? Yeah, so if you pass in, well, how do you pass in something with a side effect? Let's do an example. Yeah. Oh, sure. The question was maybe it just copies in from the back. Yeah, so, okay, let's look at another example, a different example, okay. So here we're declaring a global variable i, an array, a size that has 10 elements, all those elements are integers. We're defining a function called increment, which takes in an int x, and it increments i and increments x, okay. Every node's name takes x plus plus y, or i plus plus, yeah. Okay, then in our main function, we set i to be one. We set the first index of a, so a one to be one. And then we set a two to be two. And then we call increment ai. And now we print out the values of i, a one, and a two. So it's passed by value semantics, what would this print out? So what's the value that gets passed in the increment? It's passed by value, one, right? So it evaluates its arguments, it's the actual parameters, it copies the value one into the function, it increments one, and then it sets, it increments i, so i will now be two. And so it's gonna print out two, one, one, right? Two, one, two, exactly, yes. Making sure you're still alive. So what about pass by reference? Let's say this is pass by reference. Two, two, two, right? So here we have, so if we're passing by reference, we evaluate ai, what's ai? Whatever, so when we're passing by reference, we're gonna bound that to whatever the location ai is. Ai at the location time is at a bracket one. So we pass that in, and we increment that. So that'll increment a one to two, and increment i to two. So we'll do two, two, one, right? Did I say that right? Two, two, two, good. Whole bunch of compilers, even though they're only half full. All right, so what happens if it's pass by name? Two, one, three, three, one, two. One, two, one, we're gonna shout out a bunch of numbers. 132, oh, I don't know where it turns to. Okay, let's look at our specialization of this function, right, so that's what I think about. So when we invoke this, right, we're gonna textually replace x with whatever the actual parameter is. So here we're gonna essentially pass in, do this, so remember, so yeah. So here we're going to increment i first. So what's i gonna be? Two. Then we're gonna increment ai, what's the value currently in ai? Two, and then when we increment it's gonna be, so now what's the value in i? Two, what's the value in a one? One, and what's the value in a two? Three, please hope that's right. Pretty crazy, right? This is not what you would expect, right? So what's the problem here? I would never expect that. It's kind of like a plant. Yeah, so we're, yeah, the problem, I mean, one of the problems is that we're, this i that we're passing in, which indexes into our array, is based on a global parameter, which is changing inside the function. And so every place we have an x, we're replacing it with this ai, right? And so at that point in the function, ai is evaluated, whereas before in pass by value, we evaluate the arguments, the parameters at function invocation time, not after the fact, right? Even with password, yeah? If you had passed in a j, would it have changed time? If I had passed in a j, how could I have passed in a j? Just like j equals three, how about just close to eight? Yeah, so what, so could I do that? If I create a local variable j, and could I pass in a j? Would, does test, does increment change anything about j? But what if it changes? Yeah, it would change the i, absolutely, yeah. That's part of the semantics of this increment function. Okay, let's look at one more example. I just want to show it to you, and yeah. What's the difference? Or I know the real differences by pass by me. Oh, I have to tell you, I have to tell you, so. It's only in a language like C++ where you can choose between them, they give you a way to choose. Oh, man. Yeah, so I would tell you explicitly, like here's the function, assume static scoping, what would, man, I'd be assured you'd question. Assume dynamic scoping, what's pass by value, pass by reference, pass by name, and then dynamic scoping, the same, that'd be awesome. So even though we can't do pass by name in real C++, do you feel like you could ask about pass by name? Absolutely, because it's just about, it's just code on a page, and I tell you the scientists. Okay, so look at another function real quick, okay. So here, we're defining a function p that takes in a parameter y, it sets a local j to be y, it increments i and it returns j plus y. Then here we have a function q, which has a local j, sets the global i to be zero, and then it calls p and passes in i plus j. And then so we just have main that calls q and it returns zero. So where does pass by main come in here? Inside of q, what do we call before we invoke the function? p, yeah, p. So, question, quiz to yourself when you're very, working very hard on project form, you wanna break, you can come back and think about this and go, what would the outcome here be? That's a very interesting question. I'm refreshing my mind about other things in class. Yeah, so we'll start here on something.