 They're having a little bit of Blue Monday in class. The screen has a blue tinge to it. I don't know what it is. I used two different adapters. I tried to screen in just to have a deal. I don't know. Questions for our reconvene? Somebody had a question that came up to me before class, but I want to pose to you. Can you have a recursive type? What would a recursive type be? Hmm? It's not possible. Why? It's going to go in the infinite loop, and we need to do something similar. Yeah, so it's a similar question. So it's a very broad question. But one thing could be, you think about what structs. Could a struct have itself, its own type, as a field of that struct? No, how could you ever create an object of that type? A, you need the infinite size. But there's no way to actually create that object. Similarly, you have a function that took itself as a type. How would you actually call that function? How could you write? What would that function and signature be of something that actually write that function? So there's really no difference between a structure that has itself as a field argument, as the type of its field, then as a function that either, let's say, returns itself as a parameter, or returns its own type as a parameter, or returns, accepts a parameter as its own type. Does that make sense? Is that what I'm saying, right? I don't have to draw up the examples. Any other questions on this? I think in a related note, homework seven is due today. In case you didn't see that note on the manuals. I want to hear nice fellow students. Any other questions? 100 of you that are here. Cool, so let's move on. OK, so the end of Wednesday we talked about. And actually, I don't know if you guys have looked, but we're about a month left in this semester. Don't be so happy. You'll be happy that you're moving on to other classes. You can be a little sad. It's like bittersweet, because you're leaving the class. We won't get to see each other again. So yeah, so we're actually, I'm super stoked about where we are. We have some really cool stuff to finish up here. And then we get into lambda calculus. And then we get to the end. I know. There we go. That's the problem of response, even if it's not true. OK, so we talked about what we're going to flow. We talked about calling convention. Now we're going to look at, we looked very briefly about how functions, how parameters were passed into our functions. So in C-deco calling convention that we just studied, how did a calling function pass parameters to the call E? Put it on the stack. Yeah, push it on the stack. But what did it actually push on the stack? So it copied that value and pushed it onto the stack. So we had essentially a new copy of that value onto the stack. So when looking at it from a semantic perspective, what are the semantics of passing parameters to a function? So in C or C++, what does it mean when you pass parameters into a function? Let's say you assign to that parameter in that function. What happens? Not a rhetorical question. Semantically, what happens? What do you expect to happen when you call a function passing parameters? Same values are passed to same function. I mean, parameters hide checking. Yes, so parameter types have to check. And two values are passed, so I can access exactly those values when the function takes it to the function. Right, so you get the same values that are passed in? Yeah. What does that mean? Right, so we know it's called pass by value, but maybe we haven't thought really hard about what that actually means and what that means semantically. And so we're seeing there's multiple types of approaches, pass by value, pass by reference, and pass by name. In some languages, like you know, in C++, you can actually specify you want a certain variable to be passed by reference when you're defining a function. Pass by name is something that we'll see that really kind of stretches your mind about what actually is a function called. So that's why it's really fun to look at. Okay, so the key part about pass by value is that the values in the actual parameters are copied to the function. So the function operates over copies of the parameters that are passed in. Right, this is why if you assign to a parameter inside of a function, it does not get reflected outside of that function. The actual parameter doesn't change. And we've seen, and this is why we save this for here, we don't talk about it in semantics, because we've seen exactly how this is implemented in X86 using C, right? How C codes compile and how it implements this. It literally takes a copy of that value and copies it onto the stack, right? So to the computer, these are physically different values. Some local variable A was at EVP minus something, and now it's on the stack again, because it's gonna be called and passed to some other function. Oh, these are weird. Okay. So we have our program main. I think I know what we're doing with this. Okay, we have Y is equal to four. We call test Y, we print out the value of Y, then we return Y. So now in our test function, we take in some parameter X. It's really weird looking. It's kind of hypnotic almost. It's like a weird hinge. Okay. So then we set X is equal to X plus five and we print out the value of X. So what is this program gonna output in what order? Nine and then four, right? So we know we're gonna set Y equal to four. We're gonna call test Y, we're gonna pass in Y here, and we're gonna copy that value four into this parameter X, and we're gonna say X is equal to X plus five, so that will make this X that's internal to test be nine, and we'll print out nine. Then we return Y didn't change, right? We passed by value, we copied that value into the function. Cool. So we can, oh, there's the solution on there. That's cool. Okay, so we can compile it, run it. We'll see it outputs nine and four because this is GCCC semantics that we're all familiar with, right? And the question is how to think about this using the tools we know of how to think about semantics, right? And so we know when we see main, we have a box circle diagram with Y. So we know we have a local variable Y and main, which means we have a name Y that is bound to some location and what's the value inside that location? Or, yes. Now, when we call test, what does that mean for X in our box circle diagrams? Create another box. So we have the name X bound to another box and at function and location time, what's gonna be the value inside that box? Four. Four, we are copying the value that's inside Y and putting it into the location associated with X. So we copy four there, then we say X is equal to X plus five. We know exactly how to do this semantics, right? We're saying take the value in the location associated with X, add five to it and then copy that into the value of the location associated with X, which is gonna change X to be nine. Then when we print out X, we print out the value in the location associated with X, which is nine. And then when we return, what happens to this X box? It gets automatically deallocated, right? So this box goes away, gone forever. And then when we print out Y, now we're printing out the value four. And now isn't it incredibly obvious and clear that Y should never be changed? From this box circle diagram, inside test, we created a new box for X and we copied the value four onto there. So any changes just happen there and then when it goes away, it gets automatically deallocated because it's allocated on the stack. And now we have Y has the value four. So any questions on this? This should be pretty familiar because this is what you're used to, right? These are the fun stuff, pass by reference. So what's the difference for people that are familiar with C++ that have used this? Yeah, so it's, well, how it does it under the hood we don't really care about, right? It could do it in a number of different ways. The point is that when we assign to that variable, we are now assigning to that actual parameter that was passed in, right? So the way to think about this is that now instead of our parameters having their own boxes, at function invocation time, the parameters are now bound to the same box that was passed in, right? And this will then help us think about how to think and do pass by reference. So this means that the actual parameters must be L values. We can never pass in an R value to a pass by reference. Yeah, we need a location, right? Because we can write to that value, we need to write to some location. We need to bind the parameter, let's call it X to some location. And so if you try to pass in five plus 10, that's not a location, that's just a value, that's an R value. Cool, let's look at an example. This one's a little fixed. Okay, we have the same thing. Okay, so we have the exact same code. But now here I'm using C++ syntax to say I'm passing an X by reference. So that's what the ampersand there means. Which is kind of cool because it means that now I don't have to change this code at all. Right, and the compiler will just know what to do. So, now when I compile this, what's it gonna do? Is it gonna give any errors? Yes or what? No errors? So why? Yes, so this is the key. So this is what tells, this means that under the hood, we know it's basically passing in the address of Y here and then it's setting that by dereferencing it. It's basically turning all these X's into pointers. Right, but by using it by reference like this, we don't have to worry about that or think about that. The compiler can do it however it wants to do it. That's why we don't pass in the address of Y here because that would be passing in an int star. When this function only takes in an int, that it's gonna do pass by reference on. And the key thing is this pass by reference is part of the function signature. Right, so when we invoke the function, the compiler knows exactly what to do. It knows, aha, this first parameter is a pass by reference parameter. So I think they need to compile this call differently. Okay, what's it gonna output? Nine and nine, cool. And Y, so we can see just like before, we have Y equals four. We have a name called Y bound to some location. We're gonna put the value four there. Now when we invoke test, right, now we're just binding X to that same location that it was called from. So right, instead of creating our own box, now we're binding the name X to that location that it was invoked at. And now when we see X is equal to X plus five, we're gonna change the, take the value of the location associated with X which is four, add five to it, and then copy it into the value of the location associated with X, which is here. And then when it returns, now X, the name X goes away, but the box remains. Questions pass by reference? Yes. That may be how it's implemented, but that's not how we can think, we don't need to think about it like that in the semantic way. Because from our perspective, this is exactly what happens, right? There is no box for X. It just binds the name X to whatever location was passed in. However the compiler implements that doesn't really matter for us, right? Because to us, we don't know that underneath X is actually a pointer when it compiles down. All we see that is X is an integer. And here we see, yeah, X is an integer, right? Sir, X is at, I mean, some function, even then we don't, in the box of the diagram, we won't make the box, right? Because it will mess with what it actually does. So you have an ampersand here? Anywhere else in the function, it's in the function definition somewhere, it's there, and you're making box of the diagram. So this is part of the problem with C++, right? Is there overloading the ampersand symbol in multiple different ways? I think by itself, it would be, with two arguments, does it do bitwise and? Or is that just what, a bar, a single bar is or, a caret is Xor. So I think a single ampersand with two arguments is gonna do bitwise and. And then an ampersand unary applied to one thing is going to take the address of that thing. And two ampersands are going to do and, boolean and, and then a single ampersand on a type here in the language is gonna do pass by reference. So those are all completely different operations, right? So if we were trying to pass an address of Y, well, A, that would not type check. B, so let's go back to the previous example, right? If we were to pass in here address of Y, we would copy the address associated with Y, let's call it W, we would copy that into X, and that's what would be inside X. So we can still do the address of operator, but that's why we would call it address of operator and not ampersand because ampersand is very confusing, right? We have a box and we pass it. Yes, so let's do that. Oh, that looks really ugly for some reason. I don't know if it's too zoomed in. Huh? Boolean? Oh, is that why? Excellent. Maybe. No? No, that's just bad. Yeah, it's just bad, bad fonts. Okay. Okay, so we want to change this to this end pointer like this and this to ampersand and then we need to change it like this, right? Cool. So here I have Y, I have a box associated with Y, I have four, what's the address of Y? I have a, somebody give me a, give me a number. What was it? A number. It's not a number, alpha is a symbol. All right, FF. So now, so I'm passed by value, right? And so I have X, X has a box associated with it. It's gonna be at 1, 0, 0, that's probably not right, but 1, 0, 4, let's do something like that, I don't know. Right, and so what's the value going to be inside X? 0, X, FF, right? So now where, so if I were to draw star X on this diagram, where would I point to? Y? Like this? No. It's also a box. Hope you didn't do that on your exam. But now you want it on the next one. So now here when I say star X is equal to star X plus five, what's gonna change in this diagram? This will not be nine. And then when I return, what's it gonna print out? So this is exactly what the compiler's doing underneath. It's just doing it so that you don't have to worry about it. It's passed by value, which is what the answer is. It is passed by value, simulated, passed by reference, yes. Right, but the key part is that this OX FF is copied into here, right? So that if I were to do this, if I were to do this, now before the function returns, what's gonna happen? It's gonna change the value inside X to just be four A's, which I realize I don't have a ton of space for. Now we're gonna start X point two. Somewhere else. It'll actually probably be a segmentation fault, but do I have a dereference X? No, so I won't get a segmentation fault and then when I return, what happens to this box? Goes away, gets destroyed, right? So did that change the value in Y? Or the thing that Y is pointing to? No, it changed, well, it changed the value inside Y, but this didn't change anything to do with Y, right? So this is why if you ever wanted to, in your projects, if you ever want to malloc something and set a pointer to be something that you malloced or created, some memory that you created for the heap, you need to pass them an int star star into that function. Let's go through an example. I'm seeing lots of blank faces. Let's see, int star X here. We have X, X is a pointer. What's the address of X? Sure, we'll do FF again, because it's, did you say a million? No, I said unknown. Oh, unknown, yeah, okay. We'll give it a value though. Okay, then we call getMX. What's in, I'm sorry, what's the value inside of X? That is definitely unknown. I'm gonna just draw a symbol. Now, pass by reference, or pass by value, right? Pointer, PTR is a name. It's gonna be bound to some location. What's gonna be inside pointer? Yes, after this invocation, or when this functions invoked. It's a pass by value, I guess. Yes, pass by value. Yeah, it's the squiggly thing. Gets passed into here. And then, so when we have it malloc, so malloc is gonna return, so malloc is going to create a new box for us that's of size int. It is, let's call it A, because I don't want to draw anymore. So, what's gonna change about pointer? I think we change to zero X. And then this function returns and then what happens? Nothing. This goes away. So now when I dereference star X, what happens? Segmentation fault, because I'm trying to dereference memory inside here, right? Because what gets passed in is a copy of X, right? Pass by value, and this is the important part, even though I'm passing in a pointer, I cannot change what X points to. I can change the thing that X points to, but I can't change what X itself actually points to. It changes the array because an array is a pointer to something. So when you pass that in, you're passing in the address of your array element, so you can change it. You can't make that original array point to a different array. To do that, you have to change this, and you either have to do, well, yeah, you have to do int star. I need to pass in the address of X. Now we have X that has something in it. We have memory location zero X, FF. I have pointer. So now when this gets invoked, what's the value inside pointer? Maloc returns and returns me zero X, A. What changes? Star PTR, which is here. So this is gonna change this in here to zero X, A. Now when this returns, this all goes away, and I have X pointing to this new memory location. If you ever wondered why you couldn't get memory allocated in returning it, this is why, with pointers. And then maybe you gave up. I think I've been seeing some of this code in my office hours. I think I told that person wait until we get to this part, because you'll understand. Cool, questions on this? Relationship between pass by value, pass by reference, yeah. So we go back to the example where we're using pass by reference by using the ampersand syntax. Yep. What happens when you do an address of operator on X, like inside the test function? Is that going to be the same as address of Y? Or is it going to, I imagine since it's on the stack, it would actually have its own address, but. It would be the address of Y, because it's bound, X is bound to Y, so they share the same location. So if you took the address of that. Does that mean it goes up the stack back to the previous function in order to find it? I don't know. Let's try it out. Okay, so what do we wanna do? Let's print out, I think if we just print out the address of X, I think that should give us something super interesting. And if we maybe print out here the address of Y. And let's do it before and after just to make sure. G plus plus, oh, percent X, I want a percent P. This is why I use warnings, but it is the same thing. Okay, now I'm curious as to how it actually does that. Oh, except it's, I wonder, wait a minute, this is not a Mac. Let's see what it's gonna do. Please find out what that's saying. Let's see, so we're calling, it doesn't even keep the symbols. Take two seconds to boot up my VM, I think. Now I'm really curious as to how it actually does this. What was it, G plus plus? Also did the same thing, oh, right, but you guys forgot to remind me, we wanna compile this with 32 bits. Oh, and I don't have the C plus plus standard library. I think we've reached the end of our rope. Someone wanna compile this and tell me what it does? Nobody? All right, I have one more VM to try. And then G plus plus, M32, test.cpp. Yeah, I guess I'd never use C plus plus. Anybody know the packages to install on CentOS to compile? I need the 32-bit C plus plus standard library, that's what's missing. All right. I just wanna see the symbols in there, compile the tech key. But it still doesn't, like it has two call functions in here. That's what I don't understand. Oh, printf, we have printf test, I see. We have printf test, printf again. No, that's not right. I don't know, I never looked at that. Cool. Somebody can quickly find CentOS 7 C plus plus standard libraries, I'll install it then we can try it. Any other questions? No, we're always waiting on pins and needles for this young command. While we're looking that up, we'll then go to pass by name. So pass by name is much, well, okay. So it's very different. It can be simulated with pass by value, but in a super weird way that it's not very intuitive. The idea is, and it actually maybe makes more sense when you think, I mean, if you think about programming and trying to think of what these things actually mean, I don't know if you can think back that far and put yourself in the mindset you were in when you first learned how to think about functions and function calls. So in pass by name, every place we see X, the parameter in the function, we're going to textually replace it with whatever the actual parameter is, the text of the actual parameter. So for instance, it would mean that when we invoke it here with the address of Y, it's exactly the same thing as if test was written not like this, but was written as, which would cause an error, but this is the exact way. So we go back to our original example, get rid of this, it's changed this to a percent. So in pass by name, I'm going to literally essentially textually replace what did I do? I'm gonna textually replace all those Xs with Y. And so if I did that, and let's say, so they're also in the same scope. So they're in the same scope as the function of where they were called. So all these Ys refer to this Y. So then if I print this out, what am I printing out? Yeah, so I'm actually changing that value. So then, so this is basically the definition. We're doing the textual replacement. But for this we need dynamic writing, right? Not necessarily, you need some tricks. Yeah, there are ways to do it. And we'll kind of see how it's implemented and that can give you a flavor for how it's actually done, but it's a little bit more advanced to go into how exactly that's done. Do you have a thing? It says it's recommending doing a group install on development tools, so. How do I know group install? Pseudo-yum group install is one word. And then space, quotation, development, space, tools, quotation. I can't even have this, but we'll see. Oh, and it'll use the ASU Wi-Fi. So this will be over in a second. Oh, yep, let me see plus, plus, double. But I think it's, but it's installing all the X8664. How do I install the group? How do I install the group 32 bit? Yeah, how do I install the group 32 bit? Close. For CentOS, you have to add five, three, six, to your repository, so I don't know if that takes some time. Yeah, I don't remember. I know I did it for GCC, like you can see up here. So it's libGCC, the 32 bit version, so. Yeah, I don't know. It says, all right, so let's try this. Yum, space, install, space, libstdc, plus, plus, dot, oh. Wait, oh, sorry, I'm not typing. I probably should have said. I'm gonna shout out other random letters to the bus. All right, this is updating, it's gonna update 50. We'll get back to this after, thanks. Okay, so this is actually that same example. So we have Y. So the idea is with pass by name, we're literally creating a new copy of that function where that parameter X now means Y. And if we had some crazy version of GCC where we could compile this in pass by name, we would get nine just in the same case when in the same function that was pass by value. So at first glance, this seems like, clearly this is just pass by reference. It's just a different, weird way to think about pass by reference. So when does it make a difference? So let's assume we have some global I. We have an array, a global array A of 10 elements. Then we have a function called increment, which takes S, it increments I, and then increments X. In our main function, we said I equal to one. We set A1 equal to one, A2 equals to two. Then we increment AI. So what's it gonna print out? So what would it print out in pass by value? This is the easy stuff. This is the stuff you do every day. It's only like six lines of code. What's it gonna print out for I? Two. So this also goes to illustrate the evils of global variables, right? Trying to answer the question, what is I when it is updated here and also in this function? So it depends on how many times this function is called, right? They should try to motivate you to not include global variables in your own code. Because it becomes incredibly difficult to reason about the code and what it's doing. Cool, okay, pass by value. What about pass by reference? So I is still gonna be two, but what's gonna be printed out? Two and two, right? So in pass by reference, it's gonna bind X to this location AI and that AI is gonna be evaluated at function invocation time so that AI will point to A1, right? And so that box containing A1 is gonna be bound to X. When we increment X, it's gonna change that from one to two. So A1 will be two and A2 will also be two. And I will also be two. So we two's across the board. So now in pass by name, what is it gonna do? Oh, returns it, right? So the important thing to think about is we're doing textual replacement, right? We are replacing X with A bracket I. And remember, the important thing to remember is it's the scoping rules where it was introduced. So this means this I here is bound, well, okay, it's the same I. But this I here is bound to this global I. And that means when we do textual replacement for pass by name, it is still bound to that global I. It's not gonna magically be bound to whatever I is inside the increment. So maybe that answers your question about dynamic scoping. So what does this function look like? We have increment AI, and we first increment I, and then we do AI plus plus. So now what is this gonna change? Yeah, so A2 is now gonna be three. So this is going to output two, one, three, right? I is still gonna be two, A1 is still gonna be one, and A2 is gonna be three. On a fake compiler that actually implements this. Questions on this? This is pretty tricky. It makes for some interesting problems. So I declare local variable integer I inside increment. Yes. That will be a tie pattern, right? No. No, it's index error. No. Same, declare error. Nope. Because I is bound to that thing. Yep, so this I would now refer to your local I, and we'd increment that. So here, let's look at this. So just A of I is, I inside A of I is bound to global one. Everything else will be local. Yes, I think so. So there's a way I can change this font. Font, not great in the way of font options. Do you want it bigger, smaller, or not this at all? There was preferences. Yeah, I don't know what that's gonna do. Yeah. Okay, that's all. Before the font, yeah, let me know. I want, what's the mono space, Tom? Font? Have you seen? I actually can't remember what it is on. Is it courier? Yeah. For your hands? Yeah. Good enough. It's ugly. All right, whatever. Gotta go with what you got. Okay. So let's say it's equal to 10, or zero, whatever. Right? So now I, global I is one. So what does this I refer to here? One. So just move. This global, so this I is one, which refers to a global I. So it's still static scoping. So this I refers to this global I. So when we basically do our replacement here, when we replace this X with AI, that AI came from this scoping. So that I refers to the global I. So it will still increment, well it will increment a one. So it'll be one, two, two. Excuse me, because this I will not change, this I plus plus will change this local I and not the global I. So this I refers to this I, but when we replace A of I here from here, because it came from that scope, it still refers to the global I. It doesn't change just because we're being passed by name. So basically we're saying, hey at every point in X invoke your, invoke this thing again to get me a new value. All right, you got something for me? Let's try YUM install compact LIBSTDC plus plus dash 296.I686. Yep, sorry, oh, sorry. 296? 296.I686. Oh, well, good job. Okay, now the question is does this thing actually work? It's clearly the wrong one. That's weird. Hey, the docs. No, but see, it's doing X86. I could try like YUM search or something. Yeah, that's why I use the boot too, but. All right. Okay, so let's go back here and have another example. Cool. Okay, so now we have another example, we have a global I, we have a local global function called P, which takes in a parameter Y. It sets a local variable J to be Y, it does I plus plus, and then it returns J plus Y. So now we have a function Q, we set J to be two, we set I global I to be zero, and then we print out what's the return of calling function P and passing in I plus J. And in our main function, we just call Q and then return zero. So what would this return, what would this print out in pass by value? So let's get here to Q, J is two, global I is zero. What are we passing into P? Two. Two, passing in by value, so we're copying it into two. So Y is now two, so J is now two, we increment I, what was I? Zero. Zero, so it's now one, so we're returning two plus one. Two plus two, sorry, that's right. Two plus two, just four. I guess it's just, well, if you look at this pass by value, it looks like it just doubles it, right? It doubles the parameter and increments I. So it should print out four. But once we take this I plus J, we take that expression and every place we see Y in the function body, we're going to reevaluate that expression. So this is gonna be J is equal to I plus J, but remember that I here is this global I and the J here is this local J, local to Q, not local to P. So it's gonna look like this, J is equal to I plus J, so what's I plus J at this moment? It's gonna be two and then we do I plus plus, so I is now one, then we return J, which was two, plus I plus J, three, which is gonna return five, pretty crazy, right? Different ways of thinking, ah, right? So a couple important things here, right? This J and this J are not the same thing, right? That's one of the most important things. So it's older, older programming languages, I believe Ada uses it, I wanna say Fortran is an option, some of the other languages. It's actually, it can be faster in some sense, basically it's function inlining, so you're automatically doing function inlining, so back in the day when you're worried about function call overhead, you're like, hey, why don't I use this and then get rid of, then I don't have to worry, each function call in the code doesn't have to be an actual function call. It's also fairly easy to implement from a compiler perspective, yeah. Oh, the five is just only for the pass-by name, right? Pass-by value is still four? Yes, yes, this is just in a GCC that does pass-by name, yeah. But as you can see here, right? They were like, oh, this is great, it's simple, it kinda makes a little bit intuitive sense when you think about what does passing parameters to a function do? Well, you just replace it with whatever you pass, right? That can maybe be an easier conceptual way to think about functions if you weren't so seeped in this model of pass-by value, right? But you get into these crazy situations where you're evaluating these expressions and they can change based on where in the function that they're being changed, so it basically like, the whole community kinda switched away from pass-by name for future languages. But you can still think you could do it and so the question is, how can you do this, because it seems very different, right? So how can you get the same behavior using pass-by value? So we can simulate pass-by reference using pointers. So how can we do this behavior with pass-by value? So this kind of takes a little trick. Okay, so if we have, let's see, is this example? Okay, yeah, this is a good example, sorry. That's the next slide. This one, we have a function foo with a parameter that's never used. Here we have a local variable a, we're passing in b is equal to foo a++ and we're printing out a and b, we return zero. So substituting a++ in the function doesn't change anything. So this is still gonna print out zero, it should be zero and 10. Because a is, because the parameter's never used, it's never actually changed. This expression is never evaluated. So this is very similar to kind of lazy parameter passing at lazy evaluation. It's evaluated every time it's actually used. Okay, how do you actually do this? So back to our example, we have i, we have our p, and we have q and main. So we're gonna do, we're gonna simulate this. By having q, we're gonna essentially take that i plus j and we're gonna turn it into a function. And then every time in here when we have y, we're gonna call a function and that will evaluate what's the current value of i plus j in return of value, and we'll use that. And then later on when we use y, we'll call it again. So this is how you can simulate pass by name with pass by value. Sorry, the ordering's a little weird here. q, so we have j is equal to two. So I lifted j to be a global variable. Depends on your language, you don't have to do that. And so we have i plus j returns i plus j. So global i plus global j. And now I change p to pass in a function pointer called y, which, what does it take in? Nothing, zero parameters and it returns an integer. And so it's just like before, except everywhere I have y, I'm now having a function call. So I say j is equal to y, i plus plus, and then I return j plus y called as a function. So now the second time of calling y, right, the value of i has been incremented, so i plus j is going to return a new value. The previous slide. This is, I think, the last slide. Depends on where we go. Let the integer be one way. Because we do that in this list. Nope, we only evaluate, it's used in a parameter, we only evaluate that when it's used in the function. Exactly, we never use that value test anywhere in the function. If we did, every time we used test, it would be incremented, a would be incremented. But because we don't, it's never incremented. So we're not evaluating these, right? And pass by value, we need to evaluate these and then pass in the result. Here we're evaluating them every time they appear in the function body, which gets into one. This would be replaced by a plus plus. What will be? If I used. In the body, yes. Not a a plus plus. Yes, it would be replaced by a plus plus. So I thought, when it will be incremented and then it will be replaced. So what is the difference if you pass plus plus a and if you pass a plus plus? Madness, which is why I'm not gonna do that in this example. It's way too much. Yeah. Yeah, so we are evaluating, pass by value, we can't like test it on L value anywhere. Like, it has to be an R value. Because a plus plus on the left-hand side can't make any sense. Similarly for features, they also can be added. We have to make such a distinction. In pass by name? Yeah. No, we have no restriction. Well, it depends on where it's used, right? So we could end up using test in the wrong place. Like if we tried to say test is equal to something and the left-hand side is a plus plus, yeah. So you'd need some run time type check to make sure that that made sense. Yeah, good check. Cool, let me see. Ah, okay, we have one more thing to do here and then we get the link back to us, so. Cool. Oh, wow, you're late, sorry.