 We've got a whole practice midterm to go through today. So very best way to do this is if you have already gone through the practice midterm. So that way, you can look at what you've done, you can look at what I've done. I'll also be, you know, I don't want to just do a midterm in front of everyone. That's super boring, so for me as well. So I'm going to rely on you to tell me what to do. So let's get started. So you have fall 2016, practice midterm and same period. It should be the same thing. It's on blackboard. Always write your name and ASU ID, right? I think that's happened before in the past at least once. Okay, problem one. Following directions, circle true if the statement is true, or circle false if the statement is false. What happens if you turn in an exam and you didn't circle anything? You're going to lose however many points this is worth. We will not do a region agreement where you get to choose all true or all false or randomly circle things. That does not work. Okay, so we have to read each of these statements and see if they're true or they're false. On the X86 architecture, the ESP register contains the address of the top of the stack, true or false. True, and I'll probably be looking at this a lot while we're doing this. So if you have a question, I don't know, and I'm not seeing you, say something. Each invocation of a specific function reuses the same function frame. False. This is exactly what function frames in the stack are trying to avoid, right? We saw that we cannot reuse the same function frame for each invocation of a function. The access link is used by the callee to reference the caller's base pointer. What is the access link used for? Which parents, right? It's used by the callee to reference the caller's base pointer. So the access link, what is the access link used for? When did we learn to look at this? To get the previous function's base pointer. To get function with call, I've got base pointer comments. What are we using it for? What's the point? Various links that were declared in the stack. Or what was that? Somebody say functions? For local functions, right? We wanted to support local functions, so we needed to add another link. So in order to get local functions, you can already look at your callers. You have, when your function is called, you have the caller's base pointer. It is saved on the stack at a fixed location. So you can look at the stack of the call chain using that base pointer. The access link is used to reference the lexical parents base pointer. So the lexical scopes base pointer. So this is false. This is also a very pretty question. It's also only worth a while. I think it was worth that half point. Lambda x dot xxy is alpha equivalent to lambda z dot zzx. Yeah, the free variable y is different. Adders of x equals 10 is a valid statement in C. Adders of x returns an r value. The whole point of r and l, l comes from it can be on the left end of assignment. Also, l needs a box, right? So we have nowhere to put 10. So this is false. It's a lot of pulses. In the C-deck recalling convention, the call e puts the return value in the eax register for a false. In the C-deck recalling convention, the caller creates space on the stack for local variables. What does the caller create space on the stack for? The parameters, yeah, the parameters, and then the called function saves the base pointer, saves the, well, I guess, yeah, saves the base pointer, and then creates space for all the local variables. On the x86 architecture, the location of the current function's frame is stored in EIP. What's stored in EIP? The next instruction to execute is the instruction pointer. The program x bracket y plus y bracket x, type checks correctly using Hindley-Milner type checking. Y false, right? Based on this, y has to be an int. And x is an array of something. And here, we're trying to access y as if it was an array, but we just said it's an int. It can't be both an int and an array. And so this does not type check. In the C-deck recalling convention, the caller pushes the arguments onto the stack. Stack allocation is automatically deallocated in C. True, when does this happen? End of scope, yes, cool. How's that, easy, hard? Both? All the above? You at least have a 50-50 shot on these, right? Question call, but you're just doing like brackets in C to make a local scope. Is there a frame created for that? Or does it just use the same frame as the function? It's a good question. I think that would depend on the compiler. Think, I think those are mostly on the scoping rules in C, so you need to know that this declaration of this, let's say we have like a, so we're saying we have like main, we have like int x, x equals 10. And then here, in here, we have int x equals 100. And we have like a print x and then a print x. I know these prints aren't actual things, right? So this is kind of a question of what happens here. So it could create a function frame here. The compiler also knows just by looking at this function main how many, how much total variables it needs. So it could create all that local space there. And so it could say give this one evp minus four. And this one it could say is that evp minus eight. And then because it knows, right? The scoping rule will say print out this x. This will print out evp minus eight. And this will print out evp minus four. So there's gonna be no things there. It could do it that way, or it could create a whole stack frame for it. I don't know exactly why GCC does it. It's like writing loops in your function. So we don't create separate function frame for loops, right? For loop, for loop. Correct. It does not for a while loop or for loop. It does to local variables, compiler knows. Yeah, I think that's probably true then. That was a good, that'd be a good argument. Yeah, so like if you do it in a while loop, if you declare variables in there, it's not gonna create a whole function frame there. So coalesce them all into one function frame. Cool, any other questions? Problem two, consider the following code in C syntax. So we have code here. Now, the first thing we wanna do is we're gonna go and read the actual instructions. Right? We don't wanna just consider the code without knowing what we're considering it for. Draw the program stack. So we have to draw something. Draw program stack. At the first execution of location one, which is specified as a comment, for some reason I cannot cross right line, sorry. Label on the stack all. So this is what we have to do. We have to, you know what? Okay, draw the function stack at the first execution of location one. We need to label all function frames. And inside each function frame, label the parameters to the function, the value of those parameters, the function's local variables and the value of those local variables. Right, so we're gonna make sure we're hitting all of these things. Next, something that's so important, it's not, it is italicized. You do not need to follow precise C-deckal calling conventions. This means the specific order you write of the arguments doesn't matter. I also am fine, well, we don't do it this way, but I guess if your arguments are interspersed with your local variables, that is kind of fine too, but it's really dirty, so I would not do that. The next line is also important. Assume static scoping and pass-by-value semantics. Right, so this is how we know how we look up variables in everything. Okay, also, sorry, quick side note, because this will already be on live by the time this posts. I had questions about this in office hours, so I went through practice, no, no, I went through fall 2015, midterm two, this question and the pass-by-value question. So I recorded those, I haven't posted them yet, but I'll get posted later today. Okay, so we have some code here. We see location one, so we want to say when this executes, what's the stack look like? Where do we start? So then what's the first function frame that's going to be on our stack? Main, and remember, we are writing our stacks, so they started hiding and we're going to go down. Your bad person could be dropped the other way. It's not true, but dropped from the correct way. You got to think from our perspective, it's going to be way easier to grade if everyone's looks exactly the same. You start doing it other ways, we have problems. Okay, so what do we have to do here? We look at the instructions, it says, okay, we just labeled the function frame, and inside which function frame label the parameters of the function, the value of those parameters, the function of local variables, the value of those variables, cool. So, do we have any parameters to main? Do we have any local variables to main? Yes, one, label X, and what's the value of X? Zero. Zero. Cool. So we basically did this first one, right? We said X equals zero. Now we're here at this line, we're going to call foo X. So now what happens to our stack? We're going to include the addresses. Label the parameters and the values of those parameters to local variables and values. But yeah, we only need to do the name and both value. Okay, so what happens next to our stack? Right, we're going to push on a new function frame for foo, and so what values is that going to have? So what parameters does it have? Y, and what's the value of Y? Zero based on this call, and does this have any local variables? What's the value of Y? Cool, and this whole thing is foo, right? So we set I equal to 10, and then here we check is Y zero. Yeah, then what happens? We're now going to call foo. So what are we passing it? So now we're going to create what on a stack? How does our stack change? A new function frame foo. So we already know from this other one that we have a parameter Y and a local variable I, and so what is the value of this invocation? So now we're here. What's the value of this invocation? Y is one, and then I is going to be 10, and we check is Y zero, no? Then what are we returning? I plus Y which is 11, and where are we putting that? So this will be 11, right? So this foo is going to return, so now everything here is gone, right? This return, the function return, that function gets automatically deallocated, it's on the stack. We set the return value here to be 11. Is that right? Yeah. You erase it or cross it out if it's something you recognize. What does the question say? Does the question say probably entire history of this stack up until location one? Just draw the program stack at the first execution of location one. That's a little sketchy. It's not really clear what you mean when you like it. If you did that and then broke next to it with an arrow, like automatically deallocated or something, that I guess would be fine, but otherwise it's not entirely clear what you mean. Did you just mess up, and so that is now no longer part of the stack or is it actually deallocated? I mean the point is that that's no longer there, right? We don't care about it anymore, that's why I erase it. So you can do like a little try, lots of scratch papers, so you can try a scratch paper, get to a point, copy it over. We'll have time for that, I'm sure. Yeah. Cool. Okay, so let me get here, and we call a bar, so what happens to our stack? New frame, gonna be bar. Cool, so what are the variables that we have? Yeah, indeed, right? And so what's the value of A? Zero. Zero? What do you mean, B and A? That's why I'm saying the order does not matter of these. Yes, it would be B and A, but we can draw like this, it's fine. Okay, B, so what's the value of B? 11? And then we get location one? So we're done. This is the important part, that's supposed to be, so it doesn't have to be super difficult. Anything else? What do we go over in a true or false section? I want you to know it, you don't need to memorize it enough to be able to crank out the exact diagrams of what everything is, but maybe that would be cool. Now you've got that in my brain, but... Maybe for a final, it's not gonna be too soon. Okay, that'd be kind of fun. Experience, yeah? Can we expect a question, really, also to write a hypothesis? What? Can we expect a question, will your process to write the calculus and everything, like we did in the last... Base point and instruction point, your answer is E, A, space two... If you're drawing a stack, it'll be similar to this question, right? But you still need to know how that stuff works. No, we're going too quick, okay. We're going to have to cover my anti-calculation stuff today, if you guys don't slow down. Okay, problem three, consider the following codency syntax. Use static scoping. What are we doing here? If parameters are passed by value, the output of this program is... If parameters are passed by reference, the output of this program is, and then if the parameters are passed by name, the output of this program is. Questions on the question? Okay, what are these dashes? That means if you're writing the output of this program and you don't include the dashes, is that actually the output of this program? No. Does this program output all of these variables on a different line? No. So don't be that person, don't do that. So we have int main, we have local variable int x equals one. We have an int a, an array of zero, one, and two. So let's see, what are some techniques for going to this? One way to do it is to do box circle diagrams, which I kind of like. So we say we have x here, and we know that it's bound to something that has one. We know we have an a here, and we know that this is actually an array. So a is actually an array pointer, and that's gonna point to some memory alpha that we'll have, I'm just gonna do kind of zero, one, two, something like that. It just kind of helps me understand what everything is, where all the values are. Questions on that? Get to this line here. I say I'm calling foo and I'm passing an x and a x. So here is where things change, right? I am passing by a value. So now I wanna figure out the output of this program. So we look at foo, and so for foo, how am I gonna draw box circle diagrams for the parameters and the local variables? Yeah, new boxes, new box circle diagrams, right? So I have a, I'm gonna have c of x and I'll have y. Okay, so what's gonna be the value inside a? One, and the value inside z? And x is equal to a plus c. What's gonna be inside x? Two, look at this difficult map. A is equal to a plus one. Y is equal to c. C is equal to y plus one. And then this returns. We get here. So what happens to my box circle diagrams? These all go away, right? These are all automatically deallocated, right? I print out. So I'm printing out x dash a zero dash a one dash a two. So it's x, right? This should be the easy one, right? And you're at the level now where you should be able to understand and simulate the execution of c code that you're given, right? So you gotta think these questions are testing two things. Similarly, actually with the previous question, right? If you don't understand what happens with function calls and returning values from functions, you will struggle with this, even if you understand the function frames. But you're at the level where you should be able to give you some code and tell me what the output is and be able to tell me all the functions that are output and all the values of all the variables. So the same thing here. Cool. So this one should be a freebie, right? Passed by value. This is what you do every day. All right, passed by reference. Where do things change in this program when we're executing it? Over here, right? So we know that it's only past all these passing semantics, right? Only change how we invoke functions. So we know that everything's the same up until here. So we'll still have x with the location one. We still have a, which has the memory address of some alpha, and then we have alpha that has the zero, one, two array. Good. Cool. Now I call this function food, now it happens. So now I have a and c, and what happens here? Yeah, a is bound to the same location as x. Which now that I write it there, I realize that's terrible. I'll go here, wow. I'm gonna call this a food to separate this from a main. Right? And I'm gonna say that a food is bound to the same location as x. So what about c? Yeah, so it's technically bound to this thing. Power and food. Now we have little variables x and y, what are they bound to? New boxes, so those are x, and this is an n for me. Cool. Okay, now we do x is equal to a plus c. So a in food is one, and c is one. One plus one is? And we put that in x food. A is equal to a plus one. So we have a food is one, plus one is two. Copy that into a food, this is gonna be two. Y is equal to c, so here we have c food, which is one. And we're gonna copy that into y food. Just here, this will be one. And then we set c is equal to y plus one. So we take y food, which is one, we add one to it, which is two, and we're gonna change c, so this is gonna change. So what happens to all of my food variables? The names go away, and the names of the parameters go away, but the names of the local variables and their boxes go away. So if the parameters are past our reference, the output of this program is? Two zero two two two zero two two. Everybody agree? Cool, questions on this? Past by value, past by reference? What? We can just write the output. Yes, you can just absolutely just write the output. A lot more, you increase your chances of being correct if you draw the box with the diagrams, I feel. Because it's very easy to make a mistake when you're doing these things. Yes? You've mentioned before that if you show work and you get the answer about some of those parameters or something, was that in the case with the box circle diagrams? Very hard to show you work on these things, but true. So it depends. It's kind of the greatest barrage at that point. Okay, same question. If parameters are past my name, the output of this program is the follow name. So we have the same program, we just repeated the code here so that it's easier not to keep flipping back and forth. Okay, so what do we do? So is anything gonna change up until here? No. No, so we'll still have our box over diagrams. We'll see, box over diagrams can help here, but there also can be a little bit confusing. So we'll do this a couple of ways. So I have X here, I have X bound to something, we have one, and then I have the same thing of C. Sorry, this is called A. A bound to, what happens? Everyone? Every C just changed the name. Every C, this C? Yeah. Yeah, so, right? This is as if every time we see an A here, we're referring to this X that's in main. And not the local X inside the food. It also means that every time we see C, we are evaluating A bracket X in the scope of main. So one way to think about this is we got to think about it. What does this function look like now? And I'm going to change, I'm gonna call this XF, YF. And so I can say that XF is equal to X main plus A main, X main, right? And then I have A, which is X main, so I have X main is equal to X main plus one. And I have Y food is equal to A, M bracket X, M. And I'm running out of room for my C. Okay, so then I have A, M, X, M is equal to YF, right? So this is this exact same program, right? So I have my X main, I have A main, and I'm gonna have two new variables, X food and Y food. So I'll draw them. And I'm gonna go through and execute this. So I have X food is equal to X main, which is one plus A main of X main. So A main is here, X main of one is one. So I'm gonna add one plus one and have two into X food, right? Then I take X main and I'm gonna increment it by one. So X main is now gonna be two. Then the next line, I'm gonna get A main of X main. So what's that gonna return? A food and store that into Y food. Then I said A main of X main is equal to Y food plus one. So it's Y food plus one. Two plus one is three. Basic skills, A main X, so what's X main right now? Two, so this is gonna change this to three. And so when this returns, all of this goes away and this is gonna output what? This is hard to do just by looking at it. Super easy to make mistakes. And when you just write down something, that's wrong, it's wrong, right? Cool, question on this? An interesting thing to think about while you're studying that can maybe help you develop some intuition for this pass by name is why is this different than the reference one, right? What about function food made it different? Yes. It is dynamic scoping. There's no dynamic scoping. But how is it that you can make A visible and replace the Y into AX? How is it that you can make A visible? Because you are replacing this expression. Yes. This expression statically, this A maps to this A and this X maps to this X, right? So you're saying that every time I want C, I want what's AX in this scope. You're not dynamically looking up A or C. If you were doing that, dynamically looking up X here, you would get this X, right? Because you would get it from this local scope. You're essentially capturing the scope of where those are used in the invocation and then in the body when they're used, that's the scope that you use. It'd be like replacing food here in the essence by replacing A and C with A and then you have to deal with the variables so that gets hard to think about. But that's basically the way to think about it is you're capturing when you, if this is invoked, what is this AX referred to? And what does A refer to? And what does X refer to? Every time this variable is used, you reevaluate this A bracket X. Any questions on this one? So we'll be another review I did of this one in the office hours. I think it'll be helpful too. So I think it's a trickier question maybe. Land a calculus. So okay, we've only used 30 minutes of our time. We're talking. Problem four, fully parenthesize the following lambda expressions. What do we use to fully parenthesize these? Obviously, parentheses. How do, sorry, that's my fault. How do we know where to put these new parentheses? Yes, but what are those instances of? Our disambiguation rules. We have disambiguation rules, right? So we're gonna add parentheses so that this expression is no longer ambiguous. All right. So at a high level, so we have application, application, application, and application here inside parentheses. And then inside here, we have application, application, application, right? So if we disambiguate several different things, right? Inside this parentheses, we have to disambiguate here. So notice when we left associated it, so we're gonna have that happen first. Here we have the same thing. We now have, we have, you can think of this, you have to think of this whole thing because it's a parentheses as its own lambda expression, right? So we're gonna, is that a question? Parenthesy. First this, then this, then that whole thing. I don't think so. No, it's the same. There's no disambiguation here. Which one is the last parentheses then? Yes, how about? The last ones, these ones. On the whole thing? Yeah. Yes. Why did you start inside of the parentheses on the right rather than the left, right? Personal preference. I thought I could explain better why we were going inside here. Because of the parentheses outside, right? Because it treats that as its own expression. So this is gonna be parsed as one expression. So we need to go inside of it. It's totally acceptable. Think about it this way. Then you don't need one on the outside. Any questions on that? Fully parenthesized, hold on. Fully parenthesized the following lambda expressions. Okay, so in a similar vein, we can just look just inside these parentheses that are already here. Right, we know this is going to be a lambda expression on its own so we can disambiguate this one first. So what's our rule about bodies function? Abstraction bodies. So from here, all the way to the end, is AX ambiguous at all? There's only one way to parse that, cool. Now we have, now we can treat this as lambda expression, lambda y dot x A y z. So we can treat this as its own expression. So another question is what do we do here, right? So how do we deal with the ambiguity of the body? Now what do we do for the body on the inside? Left associative, yeah, so we first are gonna do x A and then that apply to y and we do not need the last one. Now, is this ambiguous? Do we need to add this? Okay, you can add them, but we've already added this body. So lambda, meta variable, lambda id dot lambda expression is an expression, right? So this is going to get parsed as an expression. We have an application with this expression on the left and this expression on the right. So you can add, you can add more, don't get too crazy because you still have to read these things, right? Questions on this? So this part is critical. I know this seems very simple, right? But if you can't do this one, 100% cold, right every single time, then if you fail doing this on two and three, the other thing to type those questions, then you're never gonna get those right, right? So this is a foundational thing where if you can't do this, you really can't do anything else. Okay, circle all three variables in the following expressions, done. That's how you get minus points for circling non-free variables, right? It doesn't say you can't do anything. It also doesn't say what will happen if you do circle the non-free variables. So I'm telling you upfront, don't be surprised. So we have lambda x dot and then we have this body. So inside of here, which variables will be bound? X, so all the x's in here will be bound. So this is found, found, that's a meta variable. Found, found, then inside here, what variable's gonna be bound? X, so this x is found, so that means we get this y, what is it? It's a free variable, you're getting the variable, you're getting the variable. I gotta zoom in a little bit more. Okay, now circle all the free variables in here. So inside here, which variables are gonna be bound? X and y, which means the z is free. And inside here, we have z and x will be bound, right? So x is bound and z is bound, the y is now free. Yes, you should circle both of them. So circle all, oh you did one circle, that's fine. Oh, sorry, yes, that's fine. I mean it doesn't say what'll happen. All right, you guys did it. I literally can't do that, I'm just gonna do it. Problem five, write the result of the rename operation below the lambda expression. So here's the lambda expression x, y, z, and then parentheses x, y, z, and we're substituting x with z in here. What's the result of this going to be? Do you have to add the extra disambiguation rules here? No, because that's why they are our disambiguation rules, because we know that's exactly what they mean, right? When we write x, y, z, space, parentheses, x, y, z, we know how to parse that, right? We know how to add the disambiguation rules to it, and now I can rewrite this. Yes, question. Replacing z with x. Oh, did I do it the other way? Yeah. That's your fault, not my fault. I blindly wrote down what you said. Yes, so you want to replace z? Yes, replace z with x. x, y, x, x, y, x. That would also be something that's important to memorize. Yes. Also, don't listen to a class telling you what something is. It took a long time for somebody to raise their hands, by the way. OK. This gives you a blind place. This is a blind replace. Replace all x, z's with x's. And here, we're going to replace all a's with foo. Those are going to be lambda x dot foo x lambda y dot x foo y. And if we really wanted to be super precise, right, we would write out the application of this to each side, and it would do it step by step. That's how confident you are in your substitution operations. Can you scroll just a little bit? It'll be recorded. Got it? Got it? Right to result with substitution operation below the lambda expression. So here, we have the lambda expression x of y to lambda x dot xy, and x substituting x for lambda y dot y. So are there any three variables in the expression that we are substituting? Do we need to go back to the free variables section? And we go look again. OK. There are not any free variables in what we're trying to replace, which means that we don't have to care about that weird rule of if there are free variables in doing the renaming operation. Substitution operation, right? This rule here, so if we're trying to rename something where the meta variable is free in n, then we have to rename that expression. So let's look at this. Let's just look at this. So here, we can do this step by step. So we first have x, and we're replacing x with lambda y dot y based on the rules that we have here. So this is an application. So we are simply distributing this to each other side of the application. Here, we have lambda x dot xy, where we are replacing x with lambda y dot y. And then on the right, we have another x here where we're substituting x for lambda y dot y. OK, to do this, what's this going to return? Lambda y dot y. And this, the same thing, right? This rule right here, right? If we're trying to replace, substitute something that is the meta variable is the same that we're trying to replace, you can think of it that it cards it, right? So we don't want to replace any of those x's in here. So this is going to be lambda x. And this is going to be lambda y dot y. So is this my answer? Just so we can replace it. Here? Yes. This is rule, this rule here, where we have the case where we have lambda x dot e, right? And this meta variable is the same as the meta variable group. It is the same as the meta variable we're trying to replace. So here, we're trying to replace this ibx with some name. And so you can think of it as this guards it, right? So we don't want to replace the x in here because this x is bound here. The substitution operation, we want to replace all three x's with the expression. That's something you're going to know. It's important to lay the guy down. OK, so back to my question. Is this correct? Why? It's ambiguous. Yes, because this is what this means, right? This is not what we had. So this x, we replaced it, is going to have to be its own thing. This already had parentheses around it, so it will continue. And this x is also its own thing. Is this OK? Yes. Because this is exactly what we gave it, right? We don't need to have the disambiguated parentheses because we know how to do that. The important point is that the structure is maintained, right? When you replace this x with some arbitrary lambda expression, it better not change the parsing of the original instruction. This is very key. OK, let's go to this example. So here we have, we're replacing x with lambda z dot lambda x dot x y y z in lambda y dot x y y z. Fun fact, can you look? Wait, where is that? That's this. We're doing this function application. We're replacing the x in here with lambda z dot x x y y z. We're replacing all the x's in the body with that. Just a little e-string bonus that is in no point. OK. So what is this saying? We're trying to replace all three x's with this lambda expression. So what are the three variables in this lambda expression? Y. So y is free in here. And so we have a situation where we are trying to substitute. So we have here, we have y. And we're not trying to substitute for y. We're trying to substitute for x, so these are different. But y is a free variable in n in the lambda expression that we're trying to replace, which means that if we were to just replace x in here, this y that here is free would now be bound to this y if we do not want to happen. So what do we do? Replace the meta variable in here with something else. What do you want? W. W. Can we use x? Can we use z? No, because they appear in both these things. So let's use w. So you would do this operation. You would replace y with w. We know the result, and then you'd have this bracket thing here. Sorry, I was going faster the right of time. But we'd get lambda w dot x w w z. Substitute x in for this thing. We'll call it n. So we do that. We can drop that just in directly. We have lambda w dot x w w z x replaced with n. And then that would distribute to all of them. We know it's going to change this one. So we will have lambda w dot, I'll see. What is this? Lambda z dot lambda x dot x y y z w w z. We mean we actually, so we can't leave it like this. This is not correct. We've changed how we're parsing this body, exactly. So we need this body. So now it's still in the form lambda w dot 1, 2, 3, 4, the outer page line. This z is bound to this z. This z is a free z, just like it was before. That's important. Oh, yeah, possibly, yeah. The Hindu-Milner and the Boxerful Diagrams were the worst of midterm free. So there was already a Hindu-Milner problems on here, as we saw, right? Don't be surprised.