 Great. Good morning everyone. Welcome to class. Okay, so today, any questions on, let's see, homework due next Tuesday, and then we have a midterm next Friday. And then today after class, the table will come and we'll distribute the midterm twos. Yes. Is the final going to be everything from test one, two, and three, or is it going to be something? It'll be everything. That's basically a cumulative final. Okay. Other questions? And the final is what on that? I think it's Wednesday at 7.30 a.m. in this room. That's early. I don't know. It's a scheduling thing, right? I don't know. Scheduling and other things. Any other questions? Homework project? Yeah. I had a question about the project because we're supposed to, for the first inputs on the project, gives us all the variables. Are the t-types for that var, or there's a t-type for var on the... So what does the grammar say? It does. It does. Okay. It's a var token, right? Var is a specific type of token, so you've got to look at what does that token actually mean. Okay. And then what are the tokens going to be for the ids in the variable list? Okay. I'll take another one. Cool. Other questions? All right. Let's get to it. Okay. So parameter passing semantics that we've been looking at in this cycle. Name. Pass by name. Pass by reference. Pass by reference. Pass by value. Pass by value. So what's the difference between the three? Values are copied. Value is a copy of what? The value. The value of whatever is in that expression of the parameter. Yes. So value is a copy. What's passed by a reference? The box. Location. What does that mean by the box? In the box circle diagram, it's the box. True, but how does that... Pass a point. Does it actually pass a box into there? Yes. That's a very good question. It's an L value. Yeah, so it's passing in a location, right? So that that way that the formal parameter of the called function, right, that formal parameter refers to that same location, the same box. So thinking about it in box circle diagrams, right, it's passing in the box and it's binding the name of the actual parameter to the box. Cool. Okay, somebody want to do... Pass by name? Remaining third one? What is it? Describe it? What it does is it takes all the formal parameters and it passes in potential representation of whatever it was. Yeah, so it replaces every instance in the function of the text of whatever the parameter was that was passed in. It actually does not invoke and resolve what that expression is until it's used in the body. Okay, so we saw... In this example, we saw that here it's actually exactly like passed by reference. So here we just have y that we're passing in and so we've replaced every instance of x in this function with y. And so when we run this, it's going to output the same thing as passed by reference, nine and nine, right? Some other important things are the scope. So the scope of this use of y is going to be wherever is in here. So whatever this y refers to, right? Whatever that y refers to, it at the function invocation time is going to be what x refers to here when it does textual replacement. So then we saw another example of when this can get weird, right? So we have a global variable i and we have a global array a and we're going to call this increment function which is going to increment both i and the parameter x that gets passed in. When we call this with i equals one, we set a one to be one, a two to be two, when we call this increment a i it's actually going to increment a one or a two, a two, right? Because the very first thing that happens is it increments i so i is going to be two, the global i, and then that x plus plus is going to evaluate by substituting in a bracket i, this textual replacement here for x. And so it's going to do evaluate the i then i is two and so it's going to set increment a, a two to be three. So we can see it looks, the function will look like this and so it'll output two one three. Let's look at another yes question. What are some languages that do pass by name? It's a good question. They're, at this point they're mostly historical. I don't know them off the top of my head that I knew them at some point. It's actually fairly easy to implement, but there actually is a good parallel between this and passing in like functions and closures, that kind of thing. We'll see that kind of in a second of how you can simulate or emulate pass by name with pass by value and pass by reference. If anybody looks up on Wikipedia and pass by name languages, put it in your hand and let me know. I know there are some that did use that. Okay, you can also be, it can also be more efficient, right? Because you're not actually doing a whole function call. You're just doing a tech like an inline macro substitution in some sense. Okay, so let's look at another example. So here we have a variable i. We have a function p that takes in an integer y and sets a local variable j to be y. It increments i and then it returns j plus y. So it takes in a value and it returns, what does it return? What is the semantics of this function? Yeah, it returns 2x or 2y, in this case, since y is the parameter. It should return twice whatever this parameter gets passed in. We just stored a local variable and then we returned that variable which should be y plus y. But notice we have a side effect here in between these two lines. Where this global i is now changing. So this is, I don't know, maybe a good example of what I tried to talk about at the beginning of the class about why global variables are evil. Because it's very hard to tell exactly what this function is going to do. If you wanted to write a function that just returned twice the parameter, it shouldn't be changing global variables, right? It's hard to reason about what this program, what this is going to do. Okay, then let's look at our q function. So q sets a variable j to be 2. It then sets i to be 0. And then it's printing out what's p of i plus j. The remaining function is called q and then returns 0. So let's go through this with first pass by value. So can we do, what's the output here in pass by value? What is this question, what is this asking us basically? How many outputs are there? Just one. So what do we really want to know? Yeah, what is the return value of p passed in i plus j right here at this invocation of this function? What is it actually output? So let's think about it. Here, what's the value of j? Two. Two. What's the value of i? Zero. What's zero plus two? Two. And what's, this is going to pass in a copy of two into here. It's going to set j to be two. It's going to incur an i now to one. And it's going to turn j which is two plus y which is two, which is four. So it's just going to output four. Pass by value, you could write a function like this. You could take this code and compile it from it and it would output four. But when we invoke this p function here, how is this going to change when we pass it in i plus j? So what do we want to do? We want to try to understand how this works in pass by name. So how do we, so let's rewrite this p function replacing what with what? Y with i plus j. Y with i plus j, right? So that will help us understand what we want to do. But when we do this, what does this j refer to in this function? The one in Q. The one in Q, yeah, exactly. So it's where it's invoked, right? i and j are resolved here where they're invoked. And so this means that this i refers to the global i and this j refers to this local j, which has value two. So then looking at this, so what is this going to x with you? What's the output? What's the return of this program? Is it an answer? Answer. Final answer. Alright, you failed. You don't have a million dollars. It's not an exchange. I don't have a million dollars to give you. Left. Yes. Right? So i plus j, so this is going to be all i plus j. And remember, this comes from the pass by name parameter. So this j refers to this local j here. Right? So that value is currently two. The global i is currently zero. So the value in the local j becomes zero. Or two. Alright? We increment i to the global i one. So this value of the global i is now one. And then we're returning local j, which is two. Then we're returning i plus j again. i is now one. j is two from this local j. And so it's going to return five. Questions on this example? So it should help show you the scoping rules. Right? This j doesn't refer to this j here. Right? It also doesn't make sense how could we set a local variable j to be itself. Right? Questions on this? Yes. We have to worry about like, does this change significantly for dynamic versus static scoping? Or is that not really something we have to worry about at the same time? As good as a parameter. I think, so you would not, so I think in both case, static or dynamic, you would evaluate what i and j, what values they refer to here when the function is invoked. That's when you do the resolution between name and value. Right? So if, for instance, here, right, if we're doing static scoping, we'd say, okay, this i is this global i and this j is this local j. If we were doing dynamic scoping, we'd say this i here is, well, maybe if there's an i declared in main, it would be that i. But this j would still be this local j to q, and it wouldn't change to be this local j to p. That would be a really tricky question. I would not ask that. I think we just stick with static scoping for this. So let's look at another example. Okay, good. So we have here, we have a local function foo, which takes in a parameter test and just returns 10. So does it ever use the function, the parameter test? So we have main, main sets a to be zero. It calls foo of a plus plus. It then prints out the values of a and b and then returns zero. So what's going to happen in y? Or what do you think should happen in y? It should just constantly be returning zero, one, two, three, and then on the right split, just there. Zero, ten, one, ten, two, ten. Zero, ten? Wait, what do you mean? Is there a while loop? There's no loop, right? So it's just going to be one. It will be one and ten, won't it? One and ten? When you call foo, it will return ten, no matter what, putting that in b, and a will increment one afterwards, because it doesn't matter, but it will increment one afterwards because of the plus plus. Why would a increment? Because a plus plus increments. That's right, but it's a parameter. Where do we use a plus plus in the function foo? We don't. But it's the last copy of it. It's the last copy of it, so therefore it should evaluate the expression. But we're doing past my name, right? It does not make a copy of it. Sorry, I sort of said that. Let's do past by value first. Okay, good. So past by value, this will increment what? a by one. So a will be one. It's going to pass one into foo, it will return ten, so it will output one ten. Perfect. What about past by reference? It would make it so that any reference to a points to the location where the value points to the location that we have bound a to. So what is this that we're passing into foo? Is a plus plus, does it have a box? No. No, right? It's just a value, it returns a plus plus. It increments a, but it also just returns that r value. So this actually wouldn't fly in past by reference. We can't pass an r value into a function because it has no location. Alright, now past by name, what would it output in past by name? What would it output in why? It would say, What are the options? Well, just like, yeah. So I think it's zero on ten because like in the last example, you're going to throw in a plus plus to the function foo, and it's never going to really do anything. What do you mean not going to do anything? Well, it's not going to get returned at all. Just a plus plus itself, it kind of ends its scope after you're answering. What do you mean, so a plus plus, right? So what's the key issue here? What do we want to find out? Let's see, let's think about the other examples. So the other past by name examples, like here, what are we passing into function foo here? A value. What kind of value? An r value, right? i plus j is an r value, right? That has no location associated with it. This is never actually done. In the last example, i and j weren't actually added to each other. It's just that that's what gets replaced. That's what's put in, but this isn't put anywhere. So it's not executed. Right, so in this, how many times do we execute i plus j in this function? Twice. Twice. Why twice? Because the formal parameter y appeared twice in the function, exactly. If we had passed in i plus plus here, how many times would, if we passed in j plus plus here, how many times would j be incremented in this function? Because that's where it's used twice. So it evaluates that expression twice. Whereas in this example, how many times is test used? Zero. Zero. So how many times should a be incremented? Zero. Zero. So our function looks like this, right? We're passing in a plus plus, but we just return 10. The static constant, 10. And this is passed by an a. Passed by an a. Yeah, so then we run this. It should output zero and 10. Does that feel wrong and weird? Yes, no, why? So in this case, if we did actually, like if it foo was like, had created two local variables, a, like x and y, and assigned x equals a, a plus, or I guess x equals test, b equals test, then we would return to 10. Yes. Every time it's used, that expression is evaluated. Okay, questions on this example? So let's look at, go back to our i plus j example. So we have global i, we have local function p, takes in an integer y, we set j equal to y, i plus plus j, return j plus y. We have our q function, we set j to two, we return i equals zero, and then we have our main q and zero. So the question is, can we do something similar without using pass by name? Can we get the same semantics using our normal pass by value semantics? So what's happening every time we're using this variable y? The input. It's evaluating, not quite the input, but what is it evaluating? i plus j, right? Which is what? This is a parameter. Parameter, it's also, yeah, expression, right? The parameter is an expression, right? So it's evaluating that expression twice every time it's used. Right? Almost as if could you write a function that takes in nothing and returns i plus j? Yeah, if they were global variables, right? Let's assume we can get access to variables, but yeah, if we can get access to those variables, right? We can create a function that adds together i plus j and then pass into this, the function p, we can pass in this function and then call this function every time we want to access y, which would get the same semantics of we want this expression to be executed every time we use variable y in our program. So we can actually do this. So we can have our main function. We have our function q. Now, as we saw, so for this with scoping weirdness, at least in C, we're going to lift this local j to the global j. We're going to see that this doesn't really change anything. I want you to think about these in a different way. So we said j equal to 2. We said i equal to 0. And then we pass into p a function called i plus j. And we can easily write this function as just returning i plus j. So that i refers to the, like in the function i plus j, this i refers to the global i, this j refers to global j, this j refers to the same j, and this i refers to also the same i. Just like in our previous program, this is exactly what we had. So now we can say, hey, our function p, instead of just taking in an integer, it takes in a function pointer. So these are function pointers in C. So this means a function pointer called y that has zero parameters and returns an integer. That's what this syntax means. And then we can do our function exactly like before, but every time we use y, we call y as if it's a function. We can say j is equal to call function y, i plus plus, and return j plus y, and call y. So this is every time we want to get the value of y, we just call this function. And so you can actually compile this. You can take this code, you can compile it, run it, and it will give you five just like the other examples. Questions on this? Other questions? And crazy, right? Also super cool. This is one of the benefits of being able to pass functions into parameters. And then it's really clear to see if you look at it like this, right? If we never use variable y, right, in this program, then when we pass in this function, it's not like i plus j automatically gets called, right? It only gets called every time y executes. And it's only going to get called however many times the function p uses the variable y, right? That's another important thing. This is a runtime thing. It's not statically it sees it, so it's going to call it twice. Yes? In i plus j, the parentheses after it, is that just how you would pass the... i plus j? Yeah. This is how you pass a pointer. This means a pointer to a function which has this type right here. Okay. If you did parentheses after it, it would try to call it, which would return the value of i plus j. Exactly, yeah. Are you saying the only way to do this is to pass a function? The only way? Well, no, I'm saying that you can simulate this using pass-by-value semantics. If your language supports it, the language, the runtime, will do it for you, right? It will make sure all this stuff happens under the hood. But you can actually do this and simulate this with pass-by-value semantics. Simulate the pass-by-value. You're doing it like this. But there's more ways to simulate my name than pass-by-value. For you to do it? No. Really? Not with pass-by-value. Because you need to be able to execute that expression multiple times, i plus j. Right? In normal C, C pass-by-value semantics, there's no way you can say, hey, execute this multiple times without giving it a function to execute. Right? Otherwise it's going, when you pass it in, it's only going to evaluate i plus j once. Copy that value to the function. Are there any languages that let you specify whether you want to pass-by-value or pass-by-name a runtime? We would add runtime. Yeah. That would be crazy. I would think no. It's probably that, like in C plus plus, you can specify that certain parameters are pass-by-name, are pass-by-reference parameters. It would be the same thing here. You probably want to give people program to the option. So that some parameters are pass-by-value, some by reference, some by name. Yeah. But hopefully, part of showing you all these examples are how weird and difficult it is to think about functions when you have pass-by-name. What does this function actually do? Well, it really depends on the parameters you pass into the function and whether that function relies on any global variables that are used in that same expression. More questions? All right. So we've looked at a lot of things. We've looked at assignment semantics. What does it mean to assign one thing to another? We've looked at parameter passing semantics, different types of semantics. So now, let's go to... So whose favorite program let me just java? You can be honest with this. I'm not going to judge you. It's fine. It's fine. You guys are terrible people. So, java folks, what is the parameter passing semantics of java? Is it pass-by-value, pass-by-reference, or pass-by-name? It's a little bit of a pass-by-value, pass-by-reference, depending on what you're passing. What does that mean? If it's a primitive type, it's pass-by-value. If it's a class, it's pass-by-reference. If it's a primitive type, it's pass-by-value. Thanks, sir. So which means it would make a copy of it. If it's a object, it's pass-by-reference. Do you believe that? Thanks, sir. Sounds right. Can you set in a java function a new object? Can you change what the thing's top points do based on? It's pass-by-reference. It is pass-by-reference. It's looking exact. If you set an array, you can modify the contents in the function and it'll be updated in the function. But can you change, can you make the thing that gets passed in point to a completely, refer to a completely different array? Maybe have to specify that. Let's see. Alright, let's look at an example. So, here are some class testing with an integer foo. Here I have a class parameter passing, and here I have, oh god, it's a java function. Look at all this crap we have to do. Static void main, string, bracket, args. Alright, so we're declaring a new variable bar. We're saying bar is a new class testing. We have a new variable snap, which is a new class testing. We say bar is equal to foo. Bar dot foo is zero. We say snap dot foo is ten. And then we call a function pass by question mark, which does, passes bar and snap, and then prints out bar dot foo and snap dot foo. So, inside this function, so this function takes in two testing objects of type testing, A and B. And then what if we do B is equal to new testing. And we said B dot foo is 100, and A dot foo is 42. What is this going to output? And how does that relate to pass by value and pass by reference? If what I said is true, then what? Then it should output 10 or 142. Right, and it should, so it should, well, B is snap, yeah, should be should be 10. Should be 42 100. 42 100? Yeah. Does it? What do you think it does? Like zero and ten. Like zero and ten? Zero and ten. So what's the one thing that maybe you probably don't do often in your Java programs, which is why it's coming up as a problem here to think about? Always don't care about it until it bites you in the butt, right? You spend hours debugging. Yeah, we're using one of these parameters to point where to say, hey, this B is a new testing object. So the question is, what does this do to whatever was passed in as B? Overwrites it. Right? We're going to overwrites it. I'm not overwrites it, it just creates a different one. You're telling it to make a new one. Telling it to make a new one. In a different location. Yeah, so how does that play in? So let's think about this. So if it's passed by value, right? It's passed by value, let's say new copies of these objects are passed in, then what would be out, what would we assume the output would be if it's passed by value? Is it our value? If it's passed by value, so what would it mean to be passed by value? What does that mean that A and B are the same thing as bar and snap? Or are they completely new copies? This wasn't copies, right? So if this was passed by value, right? Which is what I think we said that primitive types are passed by value, right? So if we pass in values here, then it doesn't matter what we do to the any of the values, right? They're not going to change. So it was purely passed by value where A and B were brand new copies of these object testing, right? It should output 0 and 10. What do you mean by brand new copies, exactly? Like, just like how when you pass in an integer you get a copy of that integer. So a new number location has the... Exactly. If it was purely passed by value, well, in the way we're thinking about it, if it was purely passed by value, right? A and B would be brand new, unique, distinct locations from bar and snap. But... So, but we know from our intuition of using Java that A dot foo is going to change what? Yeah, it's going to change bar dot foo, right? Bar. Bar is passed in here, right? It's going to change this from 10 to 42. Should have given the view. Yeah, whatever. And we know from our experience with Java objects that we pass in an object into a function, right? They can call methods of that function, which can alter the member variables of our class. Or if they're public like this, they can directly access the member variables of this class, right? So we know this A dot foo should change bar dot foo to 42, right? The field of foo of bar should be changed to 42. And that we definitely know based on our experience with Java. So what is the core question? What happens to B? Yeah, what happens to B? Can I think about it? Is it hurting your brain a little bit? Is this why people named Java? No comment. No, it's good. It's fine. Actually, well, there's actually a couple different ways to think about it to try to help resolve this confusion. So if this was passed by reference, right? Then we would assume what? Let's try to think through our intuition, right? So we know it's not purely passed by value based on the way we think about that, because A gets changed. Bar's field of foo gets changed to 42, right? But if it was, so that would mean, okay, not passed by value, maybe it's passed by reference. But then if it was passed by reference, then what would happen here on this line? B equals new testing. We have the pointer and other ones. Yeah, SNAP should refer to this new testing class. And SNAP's foo should be 100. And so we should output 42 100. Execution on here. So that does not happen. So we actually get 42 10. So what's happening under the hood? How does Java do all this stuff? Think about it under the hood for a second, and then we'll bring it back up to the way we can think about it with just Java objects. So if we were to write this in C, bar and SNAP would be what? So there'd be classes like this? We'll think C++. So we do have classes. Or we can make them as structures in C. That's besides the point. That, yeah, it's only really a way of grouping functions and saying these functions are required on this object. You can still do that in C without you just don't get the compiler to help you enforce some things that you want enforced. So are bar and SNAP, if we're writing this in C, are they actual testing structures or testing classes? Or are they pointers to testing structures or testing classes? They'd be pointers, right? And so bar would be a pointer. SNAP would be a pointer. And here we're set the field of bar to zero. This would be a pointer dereference in the arrow operator, right? And then now when we pass my question mark here, these A and B are going to be testing objects, right? Using pass by value in C cement, like C, C++ cementics, right? So now does it make sense that when we say A arrow foo equals 42, that it's going to change our object that was declared up here, the SNAP, right? Because we pass it a pointer to our object and so we change the value on that object. So with B, right, if this is a testing pointer and we say B is equal to some new testing, does that change our original object? No, it just changed what's value is inside B. Remember, it's passed by value. So B gets a new value of the return address of whatever this new testing object lives. And then we set B's foo to be 100, right? That new object, this new testing object, which never affects SNAP, right? Because SNAP is still a pointer that points to this object that was declared on this second line. So in this case, if we think about all the pointers, it actually is passed by value. This is why you can change and call things on these objects because you're passing in pointers to these objects. Actually under the hood, that's how Java does everything. And this is why you think objects passed by reference, objects passed by reference, permatives passed by value, but really it's objects, it's everything is passed by value, but objects are actually pointers to objects. You can never access the raw pointer, that's kind of one of the benefits that Java gives you. You can't do pointer addition and do all this crazy stuff. But it's actually another way to think about it, that we can think about it without pointers, right? Because Java's not telling us that we have pointers, right? There's no, you could easily understand Java without ever understanding pointers, right? So the trick is really about the assignment semantics. So Java is, another way to think about it is, it's passed by value, but the assignment is assignment sharing semantics. So what does assignment sharing semantics mean? What's the normal assignment semantics? When you see A equals B, what does that usually mean? The value of the location associated with B copy it into the value of the location associated with A, right? Whereas assignment sharing semantics means bind A now to the same location that B is bound to, right? So here, because part of the problem is in Java, so if we see in Java, right, which we have in our class test, we say A is a new test, and then we say test B is equal to A, right? We say A dot foo is equal to 10. Then we print B dot foo, right? What would B dot foo output? Because A and B are both pointing to the same location in memory. Yeah, so thinking about it as pointers, right, would be that, okay, they have addresses in them, but we can actually think about it the way Java wants us to think about it, right? Because we have A, right? And here at this line, with assignment semantics, when variables are declared, they're not bound to anything by default. But here, the assignment operator means create a new test and bind that location to A. So here's our new variable test, and we're going to bind that to A, right? Now here, we declare a new variable B, but instead of B having its own location, with the assignment sharing semantics, we're now saying B is actually bound to this same location as A. So every time I access B or A here, I'm also changing B. And then this way, we get the Java semantics plus pass by value here. So here at this line, which, now at this line, B is equal to new testing, what we're doing is we're binding B, which is a variable to some new location. Whereas A is already bound on this same location, A is going to be bound to B, right? Or pass by, yeah. So anyways, there's a couple of different ways to think Java is weird. It really helps to think about how it's implemented under the hood that can help save you some time. Okay, so the last topic I want to talk about here in the runtime before we start online to calculate this. So in C and C, let's see, talk about C for a second. So when we, variables that we've seen, what are the scope of variables? Like where can variables be declared? Globally or locally, right? So they're either local variables or global variables. What about functions? Where can we define functions? Same place, global or local. Can you define local functions in C? Pretty sure you can. Can you do it in C++? You can define local functions, functions that are only available local to one function. You can define functions, methods of objects, right? But still, anybody who can create that object can call that method, right? It's not that method. Can you create functions that are local for only one method in your object? What makes variables so special? Can we have local variables and global variables? Less of a headache. You don't have to manage every single, like we don't, if every variable was a global variable, coding would require a lot more mental gymnastics to get through. You have to name things very particularly, right? But with that same argument, not apply to functions? Sustainable as a function is just like, it's already done with this. What about local variables though? You have a variable that only exists for a certain function, right? Because you only need to use that value to store some value while you're executing that function. Isn't it possible that you never write code that has one helper function that actually does something useful that's only useful to that one function? Yeah, right? So, it's one of the things to think about is, well, what does make variables so special? Or what makes functions less worthy would be another way to think about that, right? We can have global variables. We can have local variables. We can pass variables into functions. Why can't we do the same thing with functions, right? Why can't we have local functions? Why can't we pass functions into other functions? Right? And we can. It's not very easy, right? How many of you have seen that syntax for function passing in C before, C or C++ before today? Yeah, not very many people, right? It's not something that's super common that we teach, unfortunately. And so, what if we want, so now let's think about it from the language design and what we've learned about the runtime. It's a language that allows local functions. So, what does that mean specifically? So, when we have local variables, what does that mean? Right, so scope, right? So, one thing is we need functions that are valid only in the local scope. But is that it? Could we easily do that by just creating a function, maybe the compiler secretly renames that function, right? And just creates a global function that then references and then changes every location that function to that global function name. So, let's say, right, that we want to have some function, let's say int main, now we have functions, we have a local variable test, and then why not have a local variable foo, returns 10, and then later on we can say maybe something like test is equal to foo. So, you're the compiler writer, right? How would you do this? Is there anything special about foo being declared locally here? Could I have written foo as a global function? I mean, because the only thing that would be concerning would be is if you had multiple functions called foo. Right, so let's say I had a global foo, right? We know from scoping rules, so I have some function foo. I know from scoping rules here that this foo refers to what? This foo, right? So, by the scoping rules I can know this and maybe I just transform this, I'm going to call it int foo underscore main, underscore zero or something random, right? And then I can just make this be a global variable and then I can say test is equal to foo. Actually, I can't say foo, I'll say foo underscore main, underscore zero, right? So, these are the same? Yeah, we can do that, right? Finally, we can do that. But what if my main function, or what if foo actually looks something different? I'm going to try typing it now. Can you see this text right now? In just a case. What if I have int test foo, let's say for purposes of this. Can I use my trick before and just move foo up into the global scope? What's the problem? It doesn't exist. Test doesn't exist. Where does test exist? Locally in main. Yeah, locally in main, right? Test is a local variable that only exists in main scope. Yeah, so we wouldn't say that again. You would be able to access it in a function that's frame. In foo's frame pointer, right? Exactly. So, we've seen that, okay, to access global variables, we just have a global static offset, right? And to access our local variables, right? If foo was, for some reason in here, had int x equals test, right? This local x is a local variable foo. We know to use the base pointer to go index that into foo's local frame. But where does test live? In main. Yeah, in main's frame, which is not our frame. How do you do this? Make test global. Make test global? But what about multiple instances of main, right? We've got main call itself. There could be multiple instances of main on the stack. So there could be multiple copies of test. You can do it. It's easy. That's a parameter. It's really true. And you use test as the parameters. Ah, yeah. So maybe the compiler can detect this, right? So the compiler knows scope, right? It knows, okay, where is this test located? It's located in main, right? And it can see x. And it says, okay, x is a local one. So I know that main is the only variable that's used outside of foo's scope. So why don't I just change automatically this function to be int test like this? And here, in every location, I basically just add an extra fake parameter there that doesn't exist in the program and compile it like this. So will that work for this instance? But what if our function actually looks like, what if our local function looks like this? So will that strategy work of going int test, int test? What's the problem here? It's nice. Right? It's just a copy, right? So the assignment statement's not going to propagate. But based on what we're using here, just like assigning to a global variable, we want to be able to assign to a variable test, even though it exists in main scope and not in our scope. Meditate on it.