 All right, no promises on how this turns out. I don't know if we're talking this thing here, so hopefully it works well. Okay, any questions before we get started? We're going to go over the practice midterm. Question about the homework, is that okay? What was that? Question about the homework. Question about the homework? Sure. So when we're doing pass by, I mean, there's already, there's, we've passed to a B, but there's also a B that's being initialized. So the scope, so for pass by name, the scope is defined based on where that function being invoked or not the body of the function. So the actual parameters, the scope is evaluated to say, okay, this B, this B right here, at function and vocation. And then when you pass by name, all references to that parameter reference that same variable. Yeah, it may come up today, we'll see. So the parameter, it's along those lines. Sure. In pass by name, the parameter is a local variable and it's passed by name to a function and everything refers to that local variable. Now, what if the function already has a variable, the same name as that local variable and the other function, but it originally referred to the global variable. Now it would just refer to that local variable, right? No, it doesn't change any, pass by name doesn't change any of the references, right? It just says everywhere that the formal parameter is seen in the function, right? Instead of using that formal parameter, you use the invocation parameter. Okay. Which that was decided to satisfy, right? So all of those other things, even though it happens to have the same name, that doesn't matter. It's still referencing to what it was originally referring to. Exactly, because you can look at that function and see, okay, all of these A's in this function reference that local variable and not a parameter. So pass by name, all of these pass by name, pass by value, pass by reference, these are only affecting the actual, the formal parameters in the function. Okay. All right. Any other questions before we get started? Can those? Sure. So would there be any, like, when I was doing it, it seemed like there was so much beauty. Well, I did it kind of like a spring processing, like a macro substitution. Okay. And I never really ended up using some shadowing. I never really had to go outside and get the theme or the color. Rather, I was just limited to the in the player. You should probably really look at how you're doing it. The scope is defined statically. The call by, it doesn't matter, any of the parameter passing does not change the scope at all. Right. That's the whole point of static scoping is you can look at the program and say every variable usage, I can map that to declaration. Right. For everything in the entire program. And call by, pass by name, it doesn't change this at all. So it's the only thing that it changes when you see a formal parameter usage. You know, okay, I go to the invocation of that parameter. You get the actual parameter and use that. But what that refers to, it still refers to whatever it refers to statically. I've never changed it. Probably for the... I think we're going to go over an example. Yeah, all right. It was with the print out, so that's why I was... One, two, eight, till after. And then you can see if you saw questions. Any other questions? Anything else from moment three? Hello. Well, I think we're going to have some problem terms. Maybe not that bad. I think last time this happened, I even said I should get a new battery. Maybe you happen to have a nine volt battery in there? Backpack or on their person? No? So unprepared. Not an electrical engineer. Not an electrical engineer? No, that's true. Hello, battery, low battery. Yeah, that one doesn't work. I think it's going to be an exercise. Hello. Hello. Oh, good. That's a full battery. Okay. Yay. Yay, exactly. Yay indeed. Okay, so to answer that question that was in the front, the question was about problem three on the homework, and I said let's get to that at the end after we go through an example on the midterm. Any other questions? Yeah. So let's say you have some actual parameter, let's say, and you are updating that in the function to three. And then, you are using that actual parameter as an index of some value. As a what? For something? So there is an actual parameter which is having value two, let's see. And you are updating that actual parameter to some other value, let's say three. Sure. And that value you are using as an index for an array. Okay. So it will be the update value. So it's in the homework function. So it will be the updated value or it will be the prove or treat. Well, in pass by name, right, every time you see that parameter, that expression is evaluated every time you see that parameter. So something in that expression changes in between usage of that formal parameter. Then whatever that expression is going to change. But that's not the case with the value. Why not? Oh, it's not the case with what? Right, those are, maybe the expressions are evaluated before the function is called and the result is passed to the function. Okay. Let's get started. I think a lot of these questions are going to answer here. All right. So we have good old problem one. Ooh. Every favorite, typically familiar type of inference. Okay. First thing, right, read everything carefully. Always important on every exam. I really shouldn't have to put this here. You should be reading. Another good tip that maybe you're not aware of when you're taking a test is to read all the questions first before you start answering anything. And if you know the answer right away to something, you can write it. But at least read through them all and then you can go back. Not only when you're working on one problem, your subconscious brain is solving, like, the last problem. I guess that's a good idea. I guess. Okay, read everything carefully. Some statements can be tricky. I hope that's self-evident, right? It's a problem for ourselves. Okay. So here we have a defining of function f that has how many parameters? Four. Four. A, B, C, and D. And the body of this function is 1.0 plus the expression if A, then B, C, D. Otherwise, D, C, A. Okay, so since I'm super nice, I do this abstract syntax tree for you. So you can use this to solve it. Yeah, sure. Cool. Okay, so, okay. Here we have the abstract syntax tree for f. Now what we want to know is, well, first thing, right? Before we do anything, we should go look and see what the question is actually asking us to do, right? That's why it'd be something that it's not asking us to do. So it says, okay, we know the type of A, the type of B, the type of C, the type of D, and the type of f returns, and the type of f. So are these all questions that you are well equipped to answer? Yes. Yes. Awesome. Okay. So now we want to do this to understand. So we need to know some things. This is the way to do this. Sorry, I forgot to tell you this a little bit. All right. So we can keep track of some of the types that we care about, right? We want the type of A, the type of B, the type of C, the type of D, and then we need, okay, so we know that f is a function. So we know something about the type of f, right? What do we know about f from this definition here? T-A-T. How many parameters is that? Cool. We've got four parameters and returned something, right? Yeah. So we know just from this definition, right? We know f, so the type of f is a function which takes in a type of A, a type of B, a type of C, a type of D, and returns some type of T-1 that we're defining right here. Right? So which on this whole thing is T-1? Fun. No. Plus. So if fun returned one, that would mean whatever the function definition returns, right? Which doesn't really make sense. We kind of have to talk about that. Okay, so we know that whatever this node is here, which we can see is this plus operator, that has to return type T-1. And we have that constraint just by looking at this top level. I think here. Okay. Just a quick question. Yes. Are you going to be posting this? Yes. Sit here, fall asleep. Okay. Let's talk about this. I don't know. I don't know. Okay. It's fine. Okay. So now, so one thing we can do, right, we can number all of these nodes, give them each a type. I'm going to kind of skip that step because the types kind of get very long here. So anytime I need a new type, I will create one and add one here. But here's all we know about the types, right? We don't really know anything. Let me have this constraint on the type of that. So I get here to this plus. Okay. Plus, arithmetic operator. What does that tell me? What constraint does it tell me about the types of that node and its children? They all have to be the same. Yeah, exactly. So the left child and the right child, both have to be the same type and whatever they return has to be the same type. So I know this has to be a T1 and this one also has to be a T1. Do I know what T1 is yet? No. Yes. No, I don't know yet because I haven't looked at any other nodes. I just know that all three of these nodes are T1 and I know that F returns to T1. Right? But now I look at this child and I say, okay, what's the type of this child? A double flow, what's called a real? Right? Because that's kind of what you're using in the homework. That's normal. So at one point there was a real number. So what does that mean about type T1? It's real, right? So this is the constraint. The constraint right here is that T1 is a type real. Great. So now we can say, okay, T1, you are real. Perfect. Okay. Now I go to the right child of this plus node. So now this T1, I know what it is, right? I know it's a real. It's got to be a real. Okay. Now this is an if node. So what do I know about the constraints? So let's... So what do I know about the constraints of an if node? Yeah. The left-most child is S3, sort of, T1. So this has to be a Boolean. And then what else? Somebody else? What else? Yeah. The calls have to be T1. The calls have to be T1. Why? Because you want to return something that's being added to a T1, so they have to be the same place. Right. So if there's... It doesn't matter which branch I fall down or which branch I go down. Either one I choose in order for this to type type has to be the same type, right? If I go down one branch and I get a real, I go down another branch and I get an int. Well then that could be that branch. I know both of these branches have to return to T1. Yeah. That only applies though because the 1.0 plus aren't right. It wouldn't be the case if that 1.0 plus was there. Did I put reals here? What did I do here that depended on this being a 1.0? Which one? Huh? Wait. You said... So you said would this be the case if this wasn't a 1.0 here? But did I put... What did I put here? No. I mean you have that match of the type of whatever you're adding, right? Because I'm saying the two branch can return to different things if you didn't have that constraint originally. Correct. I just wanted to... But no, the problem, the constraint is that whatever the int state then returns, right? Both of the true branch and the false branch must return that same thing. We don't know what it is but they have to be the same. That's the only constraint we have. Otherwise it doesn't make... you can't type that right because the text is a variable depending on what branch you go to. So yeah, it has nothing to do with the fact that this is real. You just took another step of explaining why it starts in a specific program and the types will probably be incorrect. Okay. So now I go to this left branch. Now what does this tell me? Type A is a real or is it Boolean? It's dense. Okay. Which we know because A is on the different. We know this node has to be a Boolean and we know the type here is type of A. We know these must be the same. So I can say the type of A is a Boolean. Do I know anything else? Okay. Cool. All right. Let's go to another call. All right. So now we see a call node. What does this tell us about the call node and its children? What constraints? Left side of the call node should be a function of some type and the right side should be the parameter. So the left side should be a function and the right side should be a parameter. Yeah. So about this function how many parameters does it take? One. What is the type of that parameter? D. It's a type of D we can go a little bit instead of getting it as a type. Right? Exactly. And what does it return? T1. T1. Exactly. So we have all that information here. But just from looking at this call node that gives us this good train here. Okay. Any questions? I don't know. I don't know. I don't know. I give people a chance to ask questions. All right. So let me go to this next node. So this is what kind of operator is this? array, array access, right? So this is the array access operator. So what does this tell us about it's type and it's children's type? Yeah? C is having a type int. The right child is an int. Yeah? What about the left child? Left child is an array of int. A array of what? Int equals, sorry, tt, tt implies tt. Array of tt implies tt. Yeah, so if we, so yeah, so b, this means for this type check, right, whatever this left side is, must be an array, right, which makes sense, of, but what is an array of? Well, it's whatever its parent is, right? So it's an array of td, a function that takes in type td and returns a type t1. All right, so then I look here. And what do I know about C? It's an int. And then I look here, what I know about b. Right of functions, and each of those functions has the type, takes in a type d and returns a type t1. T1 is a real, oh. OK, so we're done here, have we seen any type errors, any contradictory, no, right. So now we got on this next branch. So now we see this is a call. So what do we know about a call? What are the constraints? What about ints and its children? What's got is what? The right child. What, is that not? Take it back, I don't know any children. So we see this call function, what do we know about it and its children, right? Yeah, 30 left child is a function and the right child is a parameter. Perfect, so then what do we know, can we write down the type of this function? Right, perfect, and that's everything that we have here from this, from this branch, right. We have ta, which is a Boolean, so this is a function that takes in a Boolean and returns an a real. Is that a function that you can write? Yeah, absolutely, another example. OK, now we're on our last node. So here we have a ray access operator. Then what do we know? What was it? Season int. Season ints, OK, this node must be an int, what do we know about the left node? The ray of its parent. The ray of its parent, exactly. So it's an array of ta goes to t1. And so I have c, here this says c is an int. Was that type text? Yeah. Yes, so we already have c as an int, so that's good. If there was any other basic type, we'd say no, that's an error. Then we say, OK, type of d is an array of Booleans, a function that takes in a Boolean and returns a real. So is that type text? And returns a t1 to the real? How do we fill in the blanks? Oh, question. Yeah, so the reason you don't get a type error because you use d as a parameter without a parameter itself, and then d as an array with a parameter because d is not a function itself, just an array of functions. Well, even if d was a function, if we pass a function, it would do another function. Right, but what you need to include the parameter is if you have a function that takes a parameter and when it doesn't, you might choose a parameter. Yeah, wait, but no, this is being passed in as a value to this function. Right, but if it was a function that took a parameter and it was being passed in, it doesn't matter because it's just being passed in a function just like passing an array in it, right? As long as a function is expecting an array or a function of whatever type that you're passing in. So yes, if it was a function that required a first parameter, a function with no parameters and you give it a function with one parameter, that's a type error. But you would infer that based on the usage here. So here we know that we're passing in d. So it's really the fact that we don't have a type error because we got no contradictory constraints. So the last thing from what we're used to with c is that this is not a call, right? You're not calling a function, there's a function that's going to, yeah, he's going to be subsequently used inside of the other function. Exactly, and how would we know if d was a call? It would have parameters, it would also be in this tree, right, this tree would be a call and we'd have d on the left and nothing on the right. That would be a call to a function with no parameter. Yeah. So if we're considering structural equivalents and we're comparing whether a race are structurally equivalent, do we need to consider the dimensions and the length of each dimension? If they have dimensions of length, then yes. Otherwise just by our assumption of truth, we just pick it up and prove it. Right on structural equivalents, we're just saying. Exactly, yeah. All right, any questions here? All right, so then what's the type of A? A bullion, the type of B? Array of type T-B, let's take D. It's an array of bullions that are termed reels. Just a term of reels. Oh, right, so just simple substitution. So we say that what we know from our analysis that for this type check, B has to be an array of functions, each of those functions takes in something of type D and returns a real. And so we just simply substitute. We say, okay, what's the type of D? Oh, D is an array of functions that take in bullions and return reels. Great, so that means B is an array of functions. Each of those functions takes in an array of functions and all of that returns a real. On the exam, if we left it as T-D, would it be marked off? If you left it as T-D, would it be marked off? Just a little less to it, I don't know. If we know, if we have a right answer for a type of D and we just left it as T-D, say it applies to that way. Uh, I would, I don't know, it's tricky. I think I would probably write a word in here of simplify as much as possible to get rid of those types. Okay, because that also helps you to make sure that you know what you're doing. You get a partial credit at least. Yes. Yeah, I would pick up a bunch of points, but it's not, it's not really what we're looking for. All right, perfect. Okay, so the type of C, all right, I moved up a little bit. I have two cameras to work with. It's actually kind of a problem. Okay, okay, so the type of C, the type of C is an int. So the type of C is an int. Type of D, so there you know it's an array of functions that take in a boolean return of real. Okay, what's the type that F returns? Real, yeah. And what's the type of F? So it's a bool, it takes in a boolean. So you guys should take a test of 150 people on it. That's an int. And then D is an array and this whole thing returns a real. So you can call function F by providing a boolean. And if this boolean is true, then it's gonna use, it's gonna pass this, it's gonna pass whatever parameter D is into the, yeah whatever, you're gonna have to create this. All types, types, yeah. On the exam, the students here probably didn't want us to show what if we do get it wrong, would that be sufficient enough, like you didn't ask for it, or if you actually want us to put it in the table? The table could be more clear. I mean this is probably your best bet is showing here where all the, like where you're putting some strengths. Be even more clear, you label each of these with a node and then you kind of like mark your constraints as you go through, yeah. Why is there an arrow real for that? Why is there one here? Yeah. What's the type of F? What does that return? Oh, okay. Right? Yeah. Cool. Probably got another question too. Okay. Problem two, so we have a list of types and we have questions about those types and we have a list of variables and we have questions about those variables. So this says for each of the following types, list the types that are equivalent, assuming structural equivalent. So do y'all remember how to do structural equivalent? Perfect. Awesome. Okay. So we can do, it's the easiest way to do this. We can do our table here of the types, right? Zero, one, two, three, four, five, six, seven, eight, nine. So zero, one, sounds really good. What if this comes before you do this? So we know that all the middles, bro, right, are gonna be the same. So I'm gonna do the check mark for equivalent and then x for non-equivalent, right? So we start off by assuming that everything is structurally equivalent, right? Questions? Just writing. All right, so zero and one, are type zero and type one structurally equivalent? We have a pointer and an integer, doesn't matter. A pointer can only be structurally equivalent to a pointer that also is pointed to the same thing, right, so you have an integer, the basic type of a pointer to a basic type. I'm not saying that. Do I need an extra line for what? So I know zero and one do not, are not structurally equivalent, right? Yep. So I've got an x, so I've approved that. Zero and two, a pointer to a t zero, so same question, right? Point or two and int and int can't be the same. Actually if we look, we see pointer, pointer, pointer, struct, struct, struct, struct, struct, struct. Can an int ever be structurally equivalent to a structure? No, it doesn't matter. No, it doesn't matter. So we can know by looking at this that these are all not structurally equivalent. That make sense? Right? This can only be half the graph. Yes, we're only gonna be half the graph. So we're just gonna go, we're gonna start here with one and two. But yeah, this is a quick check, right? So we know that these three can only possibly be structurally equivalent, right? Because they're all three pointers. We know that t four, t nine could be structurally equivalent to their structures, but they can't be structurally equivalent to each other and have pointers and structures being structurally equivalent. Okay, one and two? Why yes? So they're both pointers, and then what do you do? Compare with them pointing to, right? You say our integers and t zero structurally equivalent. So are they? Yeah, exactly. So we say t one and t two are structurally equivalent, or they remain structurally equivalent. T one, t three? So t one is a pointer to an integer. T three is a pointer to t one. So what's the full type of t three? Point or two, a pointer to an integer, right? So is that ever going to be equivalent to a pointer to an integer? Nope. And then we know t four through t nine. There's no way these can ever be structurally equivalent. Okay, type two and type three? The pointer to t zero and pointer to t one? Yes? No. No, why no? So you're using this last one. The entries are this last one, yep. So those definitely aren't structurally equivalent. And t two and t four, all of these are not structurally equivalent. So we look at t three and t four. We say are these structurally equivalent? No, why not? No, definitely not. So t three is not equivalent to any of these. All right, so now we go t four. We say, okay, it's t four and t five are they structurally equivalent? Yes. Yes, why? How many fields do these structures have? Two. Two? So they're both two, right? So that's good, that's the first sign. And then the first field is one type. It's int that matches and the second types. Int int, does it matter if the names are different? No. No. So they go great, four and five are the same. All right, four and six? No. Why no? Are they the same number? Yes. Yes? So this first one is, let's see, where are we? Four and six. So this first one is, okay, so for them to be the same, now we mean that int has to be structurally equivalent to t seven, is that the case? No. No, so we've just proved that. The other way we could look at it is we look at the second field, right? We can say it isn't int the same as an array of t one. No, can't ever be true, so not structurally equivalent. Four and seven? No, by the same reasoning with this array as the second parameter. Four and eight? No, from the same reasoning, right? So the second parameter is a function and the second parameter here is an integer, right? So can a function and an integer ever be structurally equivalent? No. And the same with t four and t nine? Right. Questions on that so far? Yeah, just a quick question. Yes? Let's say for t five, t one, eight is still structurally. So the names are the same, but the orders? Does that mean the correct answer? In our structural equivalent, it's the only thing that matters is the order. The names don't matter at all. So in that case, it wouldn't be structurally equivalent? Correct. They would be not structurally equivalent. Okay, so now we look at t five, and we say is t five structurally equivalent to c t six? No, definitely not. The second parameter here is an int. The second parameter here is an int. So we know it's definitely not. What else could we use to say it's not? It's t four, t four. Yeah, it's structurally equivalent to t four. So if t four is not structurally equivalent to t six, t nine, then t five definitely can't be structurally equivalent. But if you don't want to rely on that, so maybe we made a mistake with t four, right? We could just look briefly so we can say, okay, t five and t seven. Well, this is an array here. Array can't be the same as an integer, so that's definitely not structurally equivalent. Let me say, okay, t four and t eight. Well, this is a function here, and this is an integer on the second parameter, so that's definitely not structurally equivalent. t five and t nine, same thing, function, integer, not structurally equivalent. All right. Okay, t six. So now t six and t seven. So are these structurally equivalent? Seven, seven, eight, seven, eight, seven, eight, seven. Since t is a stroke, can you compare what's the size of that stroke? Or do you compare what's the size of that stroke? So how do you compare the types of two structures? I look inside the structure to be exact. So it's one of these kinds of recursive things, right? So you want to say, okay, if these structures to be identical, it means that all their fields in order have to be structurally equivalent. So, okay, for our first go-through here, so we have t six and t seven. So we say, is t seven structurally equivalent to t eight? Yes, right? We can look that up at our table. You can see seven, eight, we haven't drawn an explicit check mark here, because we haven't looked at it yet, but as far as we know, we're assuming that they're the same. We say, okay, that's fine. And then we say, okay, so now t six and t seven, array of t one, array of t two. Is an array of t one the same thing as an array of t two? Yes, yes. How do we know that? Because they're both structurally equivalent in our table, we have t one and t two, right? So these are both, both integers are both structurally equivalent, and we have arrays. So the arrays are equivalent if what they contain is equivalent. So for right now, we say yes, this is structurally equivalent. Okay, six and eight? No, definitely not, arrays and positives here. Six and nine? Oh, same reason. Okay, seven and eight? So look at this, t seven, t eight, are you structurally equivalent? Yes, yes. Yes, does this feel great? Now we go on to the next field. Is an array of t two the same as a function that takes in type t six, t four, in terms of n. Nope, so that means t seven and t eight are not structurally equivalent. T seven and t nine? No, definitely not, right? We have an array and a function. All right, we have t eight and t nine? Yes. Are t seven and t six structurally equivalent? Well, we have all we have in our table. So what does the table say? Yes. Yes. Okay, great. Now the functions. Do the functions have the same number of parameters? Do they have the same return type? Yes. Do they have the same first type? Are these two first types structurally equivalent? T four, t six, no, so this whole thing is not structurally equivalent, eight, nine. And then we can go through this whole thing, but we kind of know the only thing that really changed the effects of anything is t six and t seven, which we've shown that because t seven and t eight are no longer structurally equivalent, and that means t six and t seven are not structurally equivalent. All right, now I can answer this question very easily. Like I said, okay, let's reach to the following types. What's the types that are equivalent? So type t one, what types are structurally equivalent? Type t one, t one, t two, t three, t three, just t three, t five, just t one. Just, wait, t four and t five, right? T seven, just t seven, and t nine, just t nine. Any questions? We'll go with that. When we get marked up, we'll write down the same ones. Type t one, just write it down, t one, t three. So in this case, if you wrote nothing here, should you get any points? No. Yes, yes. If you wrote none, I would probably take that as, well, I think you wrote none. If you did write anything, you wrote something there. Actually, if you wrote none there, I would probably accept that, but you should write all the types that are equivalent, right, because that's what it's asking you. Because otherwise, I'd have to grade it and some of you would have to have it blank. I'd have to give them points here, right? Okay, our structure is equivalent, right? t three and t three are structurally equivalent of all the types that are. Okay, then we turn our attention to the variables. We have x, that's an int, a y that's an int, a z that's a t zero, a p and q that are a function that takes in type t five, returns an int, and r that's a function that takes in type t five, returns an int, and s that's a t five and a t that's a t six. So it says for each of the following assignment statements, indicate if the statement is valid under structural equivalence, name of equivalence, or internal name of equivalence, which should be, let me make sure I'm good on that. Okay, quick. Okay, so write a one if it's valid under name of equivalence, two if it's valid under structural equivalence, three if it's valid under internal name of equivalence, four otherwise, what's a really important thing that you might miss if you skim this? Well, four, and write all that apply, right? That would be something that would be bad if you missed. Okay, x is equal to y. Can x be equal to y under name of equivalence? No? Yeah. So why yes, why no? There's a suit to be split. No, we also defend there. Five? They share the same type but not the same name. They share the same type but not the same name. Yeah, what's the name of the type? It is. You know what you and the name are very, very important. Right, so they share the same type of name. The name is int. So name equivalence, structural equivalence, are they structural equivalence? Yes. Yeah, I hope so. And do they have internal name equivalence? Yeah. Right. So why, if I had, let's say, who, are these name equivalence? Why are they different? What was that? It's not the type. Right, this is a, I've created a new type. Right, it doesn't have a name, it's an array of integers. Right, whereas here I'm using a type that already exists which is a type int, so int exists. So these are type instructors, right? I as a programmer am creating new types. And here I have not given them names, so these are anonymous types. Are they internal name equivalence? Are they? Let me have a minter and do this. Are they internal name equivalence? I was going to ask about that. Oh, there you are. I was going to ask about the person. Yeah, why are those internal name equivalence? Because they are, they have the, they have, if they're name equivalent, they have to be internal name. Like they have to have the same, they have the same name, the name is integer, that means internally they have to be represented by the same name. And assign two different names to each of them so when you compare them. Right, it's two different decorations of anonymous functions. So there's two different anonymous functions. Two different anonymous types here because they happen on different lines. So, y and z, are they name equivalent? No, right? Because they have different names, t, zero, and int. Those are different names. So, not name equivalent. Are they structurally equivalent? Yes. Yep. Are they, do they have internal name equivalence? No. No, because they're t, zero is defined here and int is defined by v, five. Okay. v is equal to q? Yes? So you said if it's name equivalent then it has to be internal. But if it's internal name equivalent, does that also have to be name equivalent? If it's in, no, no, because they don't have an explicit name. Right, so yeah, internal name is before the last. Okay, let's look at c, q. So, are they name equivalent? What's their name? What's the name of the function? It doesn't have a name, so they're not, so it's not name equivalent. Are they structurally equivalent? Yeah? Are they internal name equivalent? Yes. Yes. All right, so that's your question. So here's, that's right, not name equivalent but the internal name equivalent. Okay, q and r. Are q and r, so q is here, r is here. Are they name equivalent? No. No, are they structurally equivalent? Yes. Are they internal name equivalent? No. No, right, because they're defined on separate lines. They are two different anonymous functions that have, or anonymous types that happen to be structurally equivalent. Okay, c is equal to p, s. Or call p as a function to pass in an s. So is this a valid, does this function call type A? Yes. So p as a function that takes in a t5 returns an in. S is a t5, right? So then what is p of s return? An int, and so is an int and z, is it name equivalent? No. No? Is it structurally equivalent? Yes. Is it internal name equivalent? Okay. All right, x is equal to pt. What's the type of p? t5 returns an int. What's the type of t is t6? t6 and t5 are equivalent, right? t6 and t5 are what? R, equivalent. Are they? R. T5 and t6, no, are not equivalent. So then it doesn't work. So then it doesn't work, right? Exactly, you can't call that. That's a type error here. And what we do is? Call R. Call R, otherwise. Huh? You can't specify what it is. Keep going, yeah, the question. Well, it depends on what it is. 2 equals R, why exactly is it not internal? It's probably correct. 2 equals R. 2 equals R? Yeah. Because they're not the same definition of an anonymous type. So here I'm defining two variables p and q that have the same anonymous type. So they have the same internal name. But here on the next line I'm defining new variable R that is a new anonymous type. Just because those are structurally equivalent types doesn't mean that they're internal names from one. So anytime you make a declaration of an anonymous type, it's just a particular declaration. Exactly. Yep. Is that good enough? Okay. Okay, so problem three, consider the following C code. A function foo, a function bar, a function main. Bar has a local variable called baths. That, okay, it is. It sets baths to the result of foo zero. It sets baths to the result of bar of baths. So it passes baths into bar and returns baths. The important thing to do is to look at what the question is asking us to do. Draw the program stack at the first execution of location one, specified as a comment. So this is what we care about here. All right, location one. Label on the stack all function frames and each side each function frame labeled a parameter to the function. The values of those parameters, the function's local variables and the values of the local variables. You don't need to follow precisely that the common conventions assume static scoping and pass by value semantics, right? Very important. Okay, so let's look at this. Okay, all we really have to do is simulate the execution here. So we know, so we kind of want to look ahead a little bit, right? So we know we are hitting location one when the parameter to foo is 50, right? So we know when this function, the code executes, it's gonna start executing on main. So then we can draw main's function frame, right? And main, does main have these parameters? Yes. No. No. Does that have any local variables? Yes. Does baz have a value? No. Nope, not before we execute it. Okay. So now we're gonna call the function foo. What are we passing as the argument for foo? Zero. Zero. Is zero 50? No, so we know we're not gonna hit location one. So we want to simulate the execution, but we don't really care about drawing it through. No, because we're gonna have to get rid of it, right? We can draw it and then we'll move it and maybe we should do that because I don't know. Okay. Here we have our foo where we passed in, it has a parameter x, what's the value of x? Zero. It has a local parameter, a local variable a. So as it executes, it sets a to be 10. It sets a to be 10 and then it returns x plus a. So it returns 10. So now this function returns, we go back here. This goes away. And now we set baz to be what? 10. All right. Then we call bar passing in baz. So now we're gonna have, so I don't wanna go up there, call it, that's fine, can we go next to it and see this? Yeah. Okay. So now we're gonna call bar. What's bar's parameters? What's y? What's the value of y? 10. How many local variables does y have? Two. A and D. Okay, so bar's gonna execute and it's gonna call, first thing it's gonna call is foo y. So it's gonna call, I'm gonna run over here. All right, it's gonna call foo y. So now it's a function call, so it's gonna allocate more space. So it's gonna call foo. And foo has a parameter x. What's the value of that parameter? 10. And it has a local variable a that after this executes is gonna have a value of 10. And it's gonna return 10 plus 10, which is 20. So it returns where does it point? D. Then we're gonna call foo 50. All right, create a new frame for foo. So foo has one parameter x. What's the value of that parameter? 50. Foo has one local variable a. A has the value of 10. And then we get a location of one. And then we're done. So if I'm gonna draw this in a normal way without all that stuff. Function frame for main, a function frame for bar. And a function frame for foo. If that was a local variable, it would just not be essentially function at all. Correct, okay. Yeah, any local variables, right, will be wherever right now on the stack. So we're gonna draw that. Yeah. So this is what you want for now. Yeah, just this. Yeah. Yeah. Yeah. This is sort of a way of pushing the local variable like this. The last question about the local variable. Oh, if that was a local variable, you wouldn't write it on the stack. It's not on the stack, it's a local variable. Yeah. So would it be overkill to say that the caller puts the return address, you know, these kinds of things, no? It would be overkill, you can do it, but it's not necessary. It's not why I wanted to put this on here, right, it's on this way. And so that's all you want for the homework template. Okay. Hey, hey, hey, you got your boss to watch this. He needs to help you. Yeah. So what happens if I have to print that statement anywhere in here? Why not? You're not storing values in here now. Will it close the function of return? Exactly, calls the function returns just like this first call to function foob, right? He calls it, creates a stack, brings it then returns. So yeah, we don't care about that, right? So this location, right, this is the whole stack that is currently active as that location. Hey, hey, hey, hey, hey, hey, hey, the question. I'm not, yeah. Yes, that's why X is here as 15. Exactly. So that's why I have here as, so you got to make sure you're putting the parameters here and because it's passed by value, those values are actually on the set. And other important things, right, is that A does not have a value again. So if you put a value for A into something far, that would be wrong. So the order, does the order of the variables matter? No. And then the second question is this. So wait, okay, let's rephrase that. So no, the order of the variables doesn't matter. But you should be consistent, right? If you have the same function frame multiple times and your variables are all in different orders, that's where you really don't understand what's going on here. Yeah, so the second question would be, is this what we need to know for the exam versus the C-devil that was in the slides? Well, you may need, for a question like this, this is what you have to do to draw a stack, but you may have to ask questions about the C-devil calling convention. But it wouldn't be anything involving like assembly. You would not have to read or understand the assembly or if you did, I'd give you what it is. But you should know what it is. You should know who does what with the calling convention. Those are important things. Are we always going to assume static-stoping on the test? Or will you grow in dynamic? I could do anything. You know what I'm giving you? You're just giving me more ideas. No, stop it. You don't want a good question, do you? It doesn't matter. It's okay, because I love that. It doesn't matter that it's a basic right? Yes. Why? Because, like, if you have an unidentified pointer, there's still something there in the memory, right? So you can just use the same thing as a struct. A struct is just the thing with lots of memory. Is the space not in the right? Exactly. That's why you put nothing there, because you don't know how to play it. But if you put, like, zero there, that's pretty wrong of me, because it's not zero. Some kind of product. Zero. I'm not using the same product. You're assuming it's a bunch, right? Okay. Let's finish up problem four. So that way we can get all this done. It's all recorded. All right. So the last problem. Consider the following code in C syntax. Use static-stoping. So here we have a global integer a. You have a function f that takes in the parameters x and y. Oh, those aren't in types. Sorry. I have another CD. This is actually a valid CD, because I did run this, but... So I think it assumes an integer code that's supposed to type, but it's still there. It really bothers me. Okay. So we have a function f that takes in two parameters, both of them type int. f sets a to be three. It says x is equal to x plus one. Y is equal to x minus one. Does it return anything? No. No. It's got a void type. All right. Main sets a local variable b to be zero. It declares a local array of integers called c that has four integers there. So c zero sets b1, c1, b2, c2, b3, c3, b0. Then it calls f of passing in b. And then c bracket, c bracket b. So what are the bracket operators? Pre-access, yes. Just one over that. Half hour. Okay. Calls that function, then prints out a, b, c0, c1, c2, c3, returns. Okay. Then we want to see what is this question asking us to do. The parameters are passed by value, what's the output? If the parameters are passed by reference, what's the output? If the parameters are passed by name, what's the output? So test taking tip. What do we know about the output of this program in these three different ways? What? Possibly different. Possibly different. That's one thing. One other thing. Close it? Yeah, the number that it's going to print out is always going to be the same. One, two, three, four, five, six. So if you put not six for any of these, it's a very easy way to lose points. At least put the number there. You're not sure, right? Might as well guess. Okay. I mean, do you think it's right? Is it more likely to be right than any other numbers in your actual project here? All right. So let's look at this function. All right. Pass by value. So this should be incredibly easy, right? Because this is how you post, right? This is what you've been taught and built on. So you should be able to easily do this. Okay. So pass by value. So f gets called. Does that return anything? What does f change? Since a to be three, if we pass by value, you're going to use x equals or y equals kk, right? No. No. So then, what do we have going here? So it's a. Three. What's b? Zero. Zero. C zero. One. One. C one. C two. C three. Zero. Oh. You've got a lot of points. All right. If parameters are passed by reference, the output of this program is the following. So now, does it matter what happens in this function? Yeah. Yeah. Okay. You can't really see it. Oh. I mean, super zoom in on this thing. Okay. So. Does it matter what happens in f at pass by reference? Yes. Yes. Why? Because when we assign in here, the location that is passed in is a parameter, right? So that will actually change in effect whatever is passed outside. Okay. So let's think about this. So we have b zero. So b zero, we're going to pass by reference. So b is going to get passed in for x by reference. So anytime x gets assigned to you, it's going to change the value of e. Right? Yeah. At the same time, before function of a patient, we have cb. What's cb? C zero, which is one. And what's c1? Two. Two. Okay. But we're talking about L values here, right? So we're passing in the L value of b and the L value of c1. Right? Because the semantics of pass by reference is we evaluate this and then we use that L value to pass it. Right? So is there an L value for c1? Yes. Yeah. You can draw the boxes. Right? That location right there. The location that currently has two in it. And then we're going to execute this function with pass by reference. So we said a equals three. Is that changing anything? No. It changes the global age of three, but not anything from the previous execution. Right? Okay. x is equal to x plus one. So what's the x on the right here? It's b. So we're going to make the value, the value that's associated there with x, which is b. So zero plus one is one. And then we set that into the L value associated with x. We're going to do what? We're going to set b to be one, right? Now here, the next line says x minus one. So what's x? One. One minus one is? Okay. See, it's not hard math. Okay, zero. And we're setting it to be y. What's the L value here? C one. So we said C one equal to zero, right? So then this returns when we print out. So what do we print out for a? Three. What do we print out for b? What do we print out for C zero? C zero is one. C one. Zero. C two. C three. Alright, pretty easy, right? Pass by name. Is it harder? Okay. Let's get the problem up there. Okay. So here we're going to do pass by name. So one way to think about that is that this function call is going to be changed, right? So this function call is going to be replaced by a is equal to three. b is equal to b plus one. C bracket c bracket b is equal to b minus one. And let me print all of that. So I just replaced all of the x's here with all the y's here. So if I had an int, if I had an int c here, and I said c is equal to ten, do you think I'm good here? No. Why? It's a local variable. So this instance of c, where does that define, where does that math to? Where's the definition of this use of the function c? Right above it, right? The local c, right? You know that statically. So we know the static rule, we know it's this static c. This c here, where is this, what is this referring to? The array. Exactly. So this is all done statically. So if I have two packs by name, what I'm doing is I replace all instances of the parameter x. Which is the parameter x? Here? Here? And here, right? Three places. Those are the x's I replace, and I replace them with this expression, but everything in that expression refers to where it refers to in its use. So this c does not refer to this integer c in here, right? It refers to this c here, because we know that because it's done statically. Okay, so now it's executed. So we have to hear b is 10, so we set a to be 3, right? That's what we've been doing. So b, so b is currently 0, 0 plus 1 is equal to b, so now we change b to be 1. I'm going to cross this out there. Okay, now I take b minus 1 on the right-hand side, so what's this? 0 again. Then I take c of b, what's b right now? 1. b is 1. We just updated b right here, right? So b is equal to b plus 1, so b is 1. So what's c of 1? 2. And what's c of 2? 3. So it was 3, now we're setting it to be 0. And then this function returns, and we try to talk about it now. So what's a? 3. What's b? What's c of 0? c of 1? C3? C3? Okay. All right, we've got five minutes. Questions on the different stuff? Hey, maybe we can, everything up till today, you've got things that we learned, right? So you need scope, in order to even answer this problem, you need scope and rules, all that kind of stuff. Commandant. Hey, hey, I can't hear. So if I had a function, food like this, that has local variables b and c, b is 100, it doesn't pass my name into food, from c, it returns b and c. So is this what your question is? What happens here? So we're, so this is the formal parameter x, right? Where are all the instances of this formal parameter x? Here, right? One is this. All the rest of these variables here are not the sixes, they're poorly gone b's. So if I was to search all of these b's, these all refer to that same, scatically, these all refer to this declaration of b, the local b, right? So when I do pass by name, in this b, where does this b refer to? This one, right? The one in main, exactly, the main's local variable b. Only the x is connected. Exactly, the only thing that changes when we do pass by name is we change, so we replace the name of the usage, but we don't change any of the scoping. The only thing that changes is that x. So we replace every instance of that x with this expression, where this expression, scope, has already been decided. So we know that this b corresponds to this local b. So we can say if b is equal to zero, if b is equal to b plus one, b is equal to b plus b, we'll call it b half, because this b refers to this. So this will be zero, this will be zero plus one is one, it'll be one plus a hundred is a hundred one, it'll return a hundred one, it'll bring up a hundred comma one. So let's say that same line where we have b hash, we have equal to b plus, yeah, obviously we have that. So that would also be a b half. Exactly, so all of these all refer to that b. Okay, let's go. Cool, alright. Last question. So could you get away with this, too, and the local b could read in to b half, basically. Yeah, it's something to say to be like, doing b half, right? Yeah.