 Thanks, everyone for being here today's Monday, so before we get started back into awesome slides and content we have some class things to discuss. Okay, so there's been some questions about what exactly the gradient breakdown of each of the project's homeworks midterms is going to be. So what we're going to do, the weights are definitely going to remain the same. Basically the idea was project one and two were supposed to be very simple and so you should get full credit on those. Turns out for some people it was more difficult because the submission system, whatever. So the basic idea is what we'll do is we'll take whichever is the higher of either projects one through five each have equal weight meaning they both are 7% each or basically one and two are the same weight. They're considered kind of as, you can consider them as half, they're half, they together make one project and then that means each project's 3, 4, and 5 bump up and they're 8.75%. So we'll do this whichever one is higher that will be your project grade. So you don't have to worry about that but if you're worried about going to cuss with the class or you want to calculate out what your grade could potentially be or if your maximum could be this is what you should keep in mind. Questions on that? So for the last project I had like, I didn't get three correct but I did get like 8 out of 15. But sometimes like I think test case four it would mess up with the syntax. Like it didn't show up on the test cases for the grading but it did show up on my own. Then I would probably not complain about something like that. So would I get the 50% reduction or do you like add... So whatever the grading, whatever is on the submission system, right? Yeah. So that's fine. Yeah. Okay. Awesome. Yeah. Any other general questions like that about... So then how does your score be proportional based on... So we pretty much actually have the project for grades. Most of them we'll post them later. We're kind of waiting today if there's any late submissions. But yeah, the average was like a 68 of those that submitted. So that should be pretty good. Any other questions about this grading policy for project, for grading projects? Yeah. That's true. Hi. Hey. Hey. What are you guys doing? Hi. I just wanted to say thank you for the extra two days. Oh. You're welcome. All right. What's your name? I mean it was your fellow students. All right. Anything else? That's a weird comment. Yes, thanks. Anything else? Nothing else. It's pretty clear, right? So you should be able to go home, calculate exactly what these two numbers are because these are grade or one. If you do the math wrong, it's not my fault, right? Okay. All right. Any questions on this? So let's take care of the first issue. Let's talk about, I guess we could do homeworks next. Okay. So homeworks, I said at the beginning that there would be six homework assignments. But when I was looking at the schedule, we really only had time for five homework assignments. And I know it's a huge bummer to all of you to miss out on that six homework assignment. So what I was planning on doing is you can do, I will issue a six homework assignment. If you submit that, the motion you get out of it is 70 out of 100, but it will replace like your lowest homework score. Got it. So if you submitted a homework late or missed the homework, you can kind of use this as a little replacement. You have to actually do the homework, right? Oh, you said the motion. Get that. So if you get 70% of whatever you submit. Okay. And obviously it's not greater than anything. It won't affect your grade, right? Questions on that? Comments? More comments? No, no more comments today. Yeah. Any questions on the homework? Do you want more projects? The project's a lot. Any questions on homework? All right. So done with homework? Okay. So now about projects. So the TA has been getting inside my head and he thinks it was a good idea and I think it's a good idea. What we'll do is you can submit either project three or project four late, either one, only one, and you can get at most 70% of whatever you get. So you basically have from now until project five is due to resubmit one of those, whichever one you submit latest is the grade you will take. Yeah. So I know a lot of you are really close on getting one of those to work. So get it working. Obviously we'll check for activity violations, so please don't take the easy way out. Yeah. So if you do the work, you will get points on one of those projects. So questions. This should be pretty much everything you need to know should I drop this class from now until before, right? Any questions? Nothing? Yeah. If you resubmit project three, it's no. And then with the 70% score? It won't, it won't, it won't, you're having to get lower. No, no, yeah. It's whatever is higher, for example. I mean, it could negatively impact you. You submitted somebody else's code and then we found it and then now you've done bad things so it could deal with that. I don't want to deal with it, so don't do it. Yeah. Basically if you've got 70% on either, on both of them already, it wouldn't stop at 80%. Exactly. Yeah. I will assign next homework and next project on Wednesday. I want to give you guys at least a little bit of a breather. So this way you can send the sign to finish project three or project four, whichever is your lowest, and just get it done. Then you can have all semester to focus on project five. Yeah? If I wasn't able to turn in project three and I turned it out, do I get points or notes? You'll get whatever to this thing. So yes, you'll get as most 70% on whatever that submission is. But you can't do that for both project three and project four. It's an exclusive war. Yeah. On the fourth, this upcoming Wednesday. We don't have class next Wednesday. It's a better day. Yeah. Is there a special submission process for resubmitting? No. Just submit through the submission site and we'll get it. We'll take your latest one. So if you want to try and do both to see whatever is maximum by the date that project five is due, which I think the last week of class that Wednesday, just submit it. Submit the one that you want very last. Any time from now up until project five due date. So project five is due the last Wednesday, the second. So the second at midnight will be the due date there. So do it early. Get it done by the way you know where you stand in the class and everything is all good. More questions? Yes. Oh, sorry. We'll go here and then there. Yeah. What's Lambda calculus? Do you really want to get there? Lambda calculus is awesome. It's going to blow your mind. I'm super excited to start it. We'll probably start it next week. What was that? Yes. I don't know. I can't consider that. What do you guys think? Is that fair? Yes. What? Should you get extra credit for submitting it late? No. I don't know that you're a really unbiased audience right now. I guess so you could get more than above the 70% reduction if you got 105% but we take 70% off that. I'd say yes. That's, I guess that's fine. It's 70% of five. I don't know. Something. Anything else? Any questions? Okay. Any other general class stuff about grading or grades in general? Yes. So say for one of the projects if you had just started it late but got below 70% Just resubmit and then you'll Just resubmit. Yes. All right. Good. Now we've got to get on some material because we clearly have to get the Lambda calculus very soon. De-scarify it for everyone. All right. Two, pass by name. So here we're talking about pass by name semantics for function parameters. Yeah. Wait what? It's a type checking problem right? Yes. There's more of a five type type. Not like a job or something like that. What's the difference? So in Python we generally don't declare any variable before. In general it can be used in a particular... What are types checked in Python? And they're in Python experience. So what does that mean at runtime? It means like whenever a type is on the right-hand side against the left-hand side. So almost kind of. So in Python or JavaScript or a lot of scripting languages like Ruby types are checked at runtime dynamically. So the interpreter has metadata that says hey this variable is declared as an int and this variable is declared as a function. So if you try to assign them before it does the assignment it checks the types. Then when it's executing and if there's any error it exits. So did anyone here execute the programs that they were trying to type check? No I hope not right? That doesn't make sense. We didn't really talk about how even the semantics there were. So in that case what you're doing you're static type checking right? So you're type checking it without executing the code beforehand after parsing. So in that case you did just what Java or C or C++ does is a static type checking. The difference is we also we had implicit variables in all language which meant that we didn't have to declare something before it was used but that doesn't mean you have to type check it at runtime which is what you saw and what you implemented. Which is why languages like OCaml and ML and Haskell are kind of fun and cool because you don't have to declare types but it does intally mill their type inference to infer the type throughout the program and check that statically. So you get the fact that you don't have to declare types but it will do the type checking statically so it will find type errors for you. That was an interesting one. So in project four we get a type checker, yes. I hope you did. Alright, so what are three, we talked about three different variable parsing semantics to functions. What are those three? What is it? What's the full name of what you're talking about? What is the name of the semantics? Somebody want to help me out? What is it? Passed by name. What was the other one? That's one. Passed by reference. Passed by reference. And the third? Passed by value. Passed by value. Yeah, going back to classes. Alright, and I said passed by name so that's not it. That's the most confusing answer. Okay, so we've been looking at pass by name semantics. So what are the semantics of pass by name? So the formal parameters are replaced by the actual parameters we're going to replace. Text-wise. Yeah, text-wise. So it's as if you textually replaced all instances of the parameters in the function with whatever you pass into the function. So let's look at an example. So this is C code. So here we have a function p that takes in an integer y. It sets a local variable j to be y. It increments i. And which i is this referring to? Global. The global i? Are we using static scoping or dynamic scoping here? Static. Static, how do you know? You said the rest of the class is static. Yeah, because I said it. It's just like the type rules, right? It's that way because we said that that's how the type system works. And just like this. So we said from here on out pretty much all the examples, at least in class, will be static scoping. And if there's any question, it'll be said and specified on a midterm perhaps. OK. So we take j is equal to y. We increment the global i. And then we return j plus y. Seems pretty straightforward. Next we have a function q, which has its own local variable j, which then sets the, which i is this? Global i. Global i. And then crates out function p called with what as the actual parameter of p? i plus j. Can I do that? Y. Type? Same type. Same type, what are the types? Integers. Integers? OK, that's one reason why, yes. That's another reason. Yeah. So you have i accessible to y and j. I have accessible to i and j in the scope of q. Yeah, that's one reason. What's the third? What was that? Past by name. Because of past by name. No. So because the semantics of function invocation says that we can call a function with expressions for each of the arguments. So here we're saying hit the first parameter to this function p that we're trying to invoke. The actual parameter is the expression i plus j. OK. And now we have a function main where we just call q and then return 0. So if i was running this as a c, so is this a valid c program? No. Why not? I know it was you. Why not? Because I'm going to use past by name. But I didn't ask that. I asked if it's a valid c program. Yeah? So what's it going to output when we execute this? As a c program. So what kind of semantics does c have for function invocation? Past by value? What is it? Past by reference. How does that past by reference? But it's not. C. C. Right. So c is only past by value. C plus plus you have the option of doing past by value or past by reference. So this is past by value. What would be the output here? There's one print statement. So it outputs 6. So what gets passed into p with past by value? 2. 2? And then it returns what? 2 plus. 2. Which is? 4. What's the elementary school teacher feel like? Awesome. 4. And then what gets printed out? 4. 4. 4 gets printed out. Right? So does the value of y does the parameter that we pass into p change? Right. So what about past by reference? What would the difference here be? There'd be no difference. Why? We don't ever use j, which j? So the j in with u, that value would change to before. And that's the difference. But we don't ever access that later, so there's no difference. So if we were to access that j later, then it would look different. Does this, what changes this j? If you were to pass it by reference. Am I passing j in as p as the actual parameter? Right. Yeah. What are the semantics of passing an r value in by reference? That's a good question. What are the semantics of passing an r value in by reference? So what do you mean by r value? Right. So why is this an r value? I guess. Because why? Because it has an operator. Right. So we're taking two l values, we're adding them together to get a value. Does that have a location associated with it? No. No, we can't draw bots for i plus j. We're not assigning it anywhere to anything that has a location. So I guess that was a really tricky question. So you can't actually, this wouldn't, this would not be allowed with reference semantics. Or just with pass by reference semantics. So the compiler would say, hey, I need an l value here and you're passing in an r value. So I'm not going to compile that. Okay. So with pass by name semantics. So I'm going to guess what the output's going to be in pass by name semantics. And include accompanying guesses. Fault. Fault. Error. Ten. Thirty-two. Twenty-five. All right. One thing that may help us to think about is let's, remember we're thinking textual replacement here. So let's think about what is this function p that's going to be executed where we replace all instances of what with what in the function. Replace what? Why with i plus j? Replace y in function p with i plus j. Right. So that's the semantics here at pass by name is we want to replace all the y's with i plus j. So you can think of it as, as we have this function call and we say in j is equal to i plus j, i plus plus, return j plus i plus j. So, but what are these j's and i's referred to? Which, so I should say which i does this refer to here? Global i. Definitely. Right. So remember we talked a little bit about on Wednesday that when you do pass by name reference, the scope of wherever the function is involved that the parameters are used. So wherever those are bound to, so here i is bound to the global i. What's j bound to here? The local j which has the value two. Right. So it's not going to affect the j in the function. So we just need to keep it straight in our heads that this i plus j returns, refers to global i and global j. So, if I compiled this with a special version of GCC that allowed pass by name and I ran it, what would the output be? I don't know. Truthful answers. I was waiting for somebody to raise their hand. Nobody wants to raise their hand? Yeah. Well wouldn't i just have a value that was already in memory of this, where you get the sign it in and you can just go in and my view sign is zero. Right. We assign i zero right here. So that's good. So now that you know that i has the value zero, what's going to happen? So on this line, what's the j that's local to the function p? What is that j going to be? Two? So it's going to be i which is zero, j. And then i plus plus is going to be what? Increment i to be one. Now we're going to return j. So which j is this? Two. Two. The one that is local. It's going to be two plus i plus j. What's i plus j now? Three. Three? So what's this function going to return? Five. Five. So why do you return five and not four? It's going to bring you down. Yeah. Because i is reference to the global function. Right. So and what happened to i during the function call? It got suspended by one. Right. So this function that we called is using this global bit of data that we're using our expression to pass by name. So that messed up, that changed what our expression i plus j was. Right. And depending on if i was incremented more here or the orderings of these, if i was, the i plus plus was the first thing that happened, that would change what value we got back from this function. Does this seem like an easy way to code? Yeah. If in q we set i equal to one way or here. So if i was one, how would that change things? So it would be one plus two would be three. And then it would increment i again. So i would be two. And then it would be three plus two plus two would be seven. Too much math, guys. Yeah, that's a really good example. That's why you need calculators. So yeah, pretty crazy way to code, right? So this is why we're not programming anything because I have this pass by name. So let's look at another aspect of pass by name. So here we just have a function foo that takes in a parameter called test and just returns ten. And then we have a function made that says in a is equal to zero. It says integer b is equal to foo a plus plus. And it prints out the values of a and b. So in pass by name or pass by value, what's the output here? What's a going to be here when we get to this print out? One. And what's b going to be? Ten. Ten. What about pass by reference? By oh no. It would be zero ten. Be zero ten? I think it would be. Yeah. That's a tricky question of what is a plus plus return? I think it's going to use the value of a. So use a as a reference. Pass that in but it doesn't really matter if you get ten back. And then it should increment a. Zero ten. Zero ten. Why would it be? Oh, sorry. One ten. Yes. Definitely. So a is definitely going to get incremented in pass by reference. Pass by reference or pass by name? In pass by reference. So yeah. So now the question is pass by name. What's pass by name in a good? Zero ten. So why zero ten? Because it's not actually getting a value from a plus plus. It's just looking to replace it so it never uses it. Right. So remember we're doing textual replacement now. So if we look at the function foo and replace everywhere that parameter test is used in the function with a plus plus. Where's a plus plus? Where's the parameter test used? Never. Never. It's never used. So we're never going to evaluate that expression. And so a plus plus is never going to get executed. Yes. Clarify. Yes. Pass by reference. Yes. That actually works. Yes. I believe this would compile pass by reference because it would use a. Get the reference to a. Pass it to the function. Nothing a would change and then it would increment a. Yeah. So pass by name like you literally copy and pasted the parameter. Exactly. Exactly. And so because of that, right, because we're never using that parameter test it never gets evaluated. So it could, in this case it would never, a would never get incremented. Yeah. Let's go to it. Inside foo if you have like a use, would it increment a inside main? So. I'm assuming not. Right. Is that a question about pass? So the other thing is, is this a scoping problem or a variable semantics problem? Yeah. So it's scoping, right? So that's, so this is just what happens at function and location time. So before we even get there, before we run the code, right, the compiler has already linked up all the variables to their locations. So we tried to use a in foo. It would say, hey, a is not defined with static scoping. But if you did it with dynamic scoping, that would make for a very interesting problem. Yeah, you guys are really good at that. I'd be a generation through questions. More questions? There's other hands over there. Cool. Okay. Then if I run this, so I'll get them out of zero and ten. So it's actually a really cool kind of byproduct here. So this is essentially some languages have what's known as lazy evaluations. In this case, function parameters aren't actually evaluated until they're used. So in this case, you can pass stuff to a function that may or may not get evaluated. Which could be, can be cool. You can have infinite data structures in Haskell. You can make an infinite list. And the list is only generated as much as you need. So it's kind of fun. But it really messes with your mind. Okay. So, is this just in some esoteric domain that you have to learn because I tell you to? Yes, that's the answer for everything. But the other thing is how could you, let's say you wanted to make a language, could you implement this behavior in C? Could you implement, so we saw that pass by reference semantics, you can implement using pass by value semantics by using pointers. Right, so you're still copying the pointer, but the pointer is through an address so you can change what something, the value that something is outside your scope with pass by value. So can you do the same thing with pass by name? Maybe if you made it by sentence. What was that? It was just a macro. If every function was a macro, how would that help? Oh, so then you could replace the, yeah. So that would be, so macro is right in just textual substitutions of function calls. Then you get into some issues though, I think would run into the problem of if you tried to define a function like this called like a plus plus here, where does this plus plus actually go in the actual evaluation of the function? And is there any scope in conflict between the parameters that are defined and the local parameters? So that might be tricky with local scope. You could maybe get away with it. So what was it that you said? What do you mean peace? So like if we were to pass in an expression that was like a plus b instead of passing in. Yeah, so actually what if we wrap, so if we think about it, right? In pass by name, every time we want to get a value from one of the parameters we have to execute something in that context that called us, right? Whatever was passed to us. So if we basically turn those into little functions and every time we want a value to call that function then it can generate a value for us and every time we use it we call that function again so any side effects get properly replicated. So we can go back to our other example and do this completely with functions in C. Now it gets a little tricky. We have to kind of change some variables around but the basic idea is here. So here we have the global I again. We have a function P which takes in an integer Y. Okay, so this is all the code that we already saw. So we have Q, blah, blah, blah, blah. We have main, we're calling Q returning zero. So this is on the left-hand side. This, yeah, you're left. That side is all the code that we already saw at pass by name. So if we replace all of these parameters with instead functions then we can actually get the same behavior. So we have to create our function Q and Q is pretty much the same. So sorry, this is a little jumbled, but... All right, where are we at? Okay, let's look at it. So we need to kind of create this function I plus J to capture this semantics here of this I plus J. And so what's this function going to return? It's going to return, which you can tell from the type signature. It's kind of a name, right? It's going to return I plus J, right? So this, the I corresponds to the global I and the J, essentially we've lifted this J instead of being local to the function Q. We're lifting it out to be global scope. Yes, you could, but we're simplifying things a little bit. That would, yeah, that would complicate things. Okay, so this function I plus J, when we call it, what does it return? I plus J, can you call it multiple times? Yep. And every time you call it, what's it going to evaluate for the values of I and J? Yeah, the global. The value of the values in the global I and J. So if anybody messes with that global I, the next time you call this function I plus J, that's going to be reflected. So we can write our function P, where instead of now taking an integer Y, now we're going to take in a function that takes in zero parameters and returns an integer. And we're going to use this every place we use a Y, we're instead going to call this function Y. So we'll set our local J to be the result of calling function Y. We're going to increment I, and then we're going to return Y, J plus the function call of Y. So is this valid C code? So then what did I pass when I called P? What am I passing in here? What was it? I think somebody just said it. Yeah. Yeah, function pointer, right? What's the type of this function pointer? It's a pointer to a function that returns an int and takes no parameters. Yes. So thinking about it like a function level, right? So what is it? You said it's, what are we talking about type two functions? There's a whole homework assignment on it. Yeah. Like the return type, the number of parameters. Right. How many parameters? Zero. Zero parameters, and what does it return? An int. An int. There we go, right? So we're passing in a function that takes in zero parameters and returns an int. Right? So in the return type inference, you calculated what the type of a function is. And this is here. Here we have a function P that takes in a function as a parameter. And every time it wants a value, it calls that. And it evaluates the current value of i plus j. So is this valid C code? Yes? No? Maybe? Yeah. That's valid code. And what happens when we run it? What's going to be output? Is that it? Is that what I'm saying? I love it. So it has a mumpel? Five. Five. Is it any different than pass by name semantics? Is the output any different? No. No, but that doesn't mean it's not different. So let's rephrase it another way. How is it different from, how's the program on the left different from the program on the right? Longer. That is correct. It's a valid statement. Does that mean it's more complicated? So yeah, so here I'm using only pass by value to emulate pass by name semantics. So this is to show you that it's not impossible, right? This is just, these are kind of just different ways to express things. But it's up to you as a language designer to specify what these semantics are so they have very well-defined semantics. And it's up to you as the programmer to understand them and to know what they mean and what the different types are and what that means semantic-wise. But under the hood you can implement, you can emulate either of them, so it's kind of cool. Questions? Pass by name? A pointer to function. Yes. It takes from there. Correct. That takes in no parameters where the void comes from. It returns an int. So this is only, the only thing is here, that's, so we didn't really get into it, but this is C syntax for specifying, specifying a function pointer. But we've seen how to define pointer types already. We've seen how to define function types, right? That's, there's no difference except for the syntax of how we express that versus our way with Hindley-Millner and with this way here. Okay. So now that you're all 100, well, let's say 80% masters of function parameter passing semantics, what are the semantics of Java? Say I say that. Potter? Pass by value. Pass by value for primitive. So primitive is being in cars, whatever the standard built-ins are. And pass by reference for objects. So is that, is that true? You think so? So what would that mean in Java? When you pass in a object. I'm not talking about how it's implated. Are there any pointers in Java? No. So it doesn't make sense to talk about pointers. All we have are objects. We have variables. We're calling functions. Let's look at an example. So maybe we can debate this, look at this some more. Okay. So here I have a function. So now we switch to Java code, right? So here I have a class called testing, which has a field called foo. And then I am defining a class called parameter passing, which I have to do all this nonsense just to like print out some things. So okay. So we finally get to our main function. So I'm going to create a new object called testing. I'm going to create a new object called snap. I'm going to set an object called bar and an object called snap. I'm going to set bar's foo to be zero. I'm going to set snap's foo to be 10. I'm going to call a function called pass by question mark. That's going to pass in bar and snap. And it's going to print out both of their foo fields. So what is it going to print out? Why do you need to know the function? So by knowing the function, we can know how they're actually changed. So if it was passed by value, would we need to know what the function is? No. If it was passed by reference, would we need to? Yes. Okay. Let's look at this function and pass that question mark. Okay. Here the formal parameters are we have a parameter a of class testing and a parameter b of class testing. So the first thing I'm going to do in this function, I'm going to say b is equal to new testing, create a new object of class testing. Then I'm going to set b's foo to be 100 and I'm going to set a's foo to be 42. So now you can see both functions. So what's the output here going to be? I guess the first question is about Java code. I sure hope so, because like it compiled and ran. So what's the output here? So is it passed by value or passed by reference? 42. That's it. So bar.foo is going to output. And output what? 42. 42. And snap.foo is going to output 10, 100. Is it passed by value or passed by reference? So are these objects? So you, you. Is it passed by value or passed by reference? The passed by question mark. Right. So then what is snap.foo going to be after this function is called? It'll be 10, but I'm passing, I'm creating a new, I'm setting b's equal to new testing here. So it's passed by reference. It'll be 100. So what's this program going to output? Is it passed by value or passed by reference? Yeah. It's passed by reference, but the b reference is lost when you finish the question mark. So it'll be the previous 10. What do you mean the b value is going to be? Isn't the so, b value in there testing places it there, but that particular reference is lost. Because of that scope, so this is going to be a deallocation error? The object, taking a new object, wouldn't it be linked into the group as a snap? So would it be linked into snaps rather than the b value? Yeah. So when it is just Java, it isn't directly passed by reference, they call it, you can reassign it, but that doesn't go back to the variable you passed on. If you do reassign it, then the changes don't, the reference doesn't. So what if we, so based on our definitions, is it passed by value or passed by reference? Passed by dereference value. Passed by dereference value. You should write a blog post about that. That's not a bad name. Okay, so have we come to a decision on what the output of this program is at least going to be? 40. 4210? Yeah. Does everybody agree? Anybody disagree? This question, everything you thought you knew about Java has been so long since you programmed a Java, thinking in pointers at C now. Is that good? Hmm? Is it good? You're thinking pointers? Yeah. That's good. You gotta have both. Okay, so, do I run this anywhere? I think so. Okay, so it does run. It definitely does. I've run this. So it all goes back to, what do we say about the semantics of Java's assignment operator? So I believe we called it sharing semantics, where the names on an equal statement, the names get rebound to a new location. Right? So when you say A is equal to a new foo, you bind the name A to some new object foo. And then when you say B is equal to A, you're saying that B is now bound to that box foo, that same new object. Right? So, Java is this weird case where you have kind of both. So, you are gonna get, so bar dot foo is gonna output 100, so it's gonna be, sorry, it's gonna be, what do you say, 4210. Or 42, yeah, 4210. That's what it's gonna output. Right? So Java has this weird, it is, so, can think of it as, let's see, is that right? I don't know that I believe this statement. Okay. So the problem is that we have an object, and we're not copying the whole object into there, right, as we've seen. So we can call methods on an object, we can change fields on that object, and those changes will propagate. All right, so then let's talk about how this is implemented under the hood, and hopefully this will help us think about it. So, what are we talking about with pass by dereference? Yeah, pass by dereference is valid. And it essentially makes a copy of that pointer inside the function. And so, if you re-put another value onto that pointer, it's lost at the end of it, and you don't see where that is. And the only reason that works is that you don't see where that is. So one language is the JVM written in that runs Java programs. C, right? Or maybe C++. I don't know if you're certain, but yeah, you got it. So I guess I think about it. I don't have as much pointer as he does, but the way I think about it is just two levels. So when it's on the first level, then it's pass by value. But when you get to that second level pass by reference, so in this case, when you object in there, that was the top level action that kind of overrode everything else. And that's why I think you're trying to find it. Right, so it's definitely pass by value, because we can't change what we pass in, what that points to. So it's definitely, at least by our semantics, the way we're defining it. So it's definitely not pass by reference, because we're not changing... There's no way we can change what bar and snap are bound to from inside this function call. So definitely not pass by reference, and definitely not pass by name, because that would be crazy. So it's got to be from our definitions pass by value. And so if we don't want to change our definitions, then we can say, well, it's passing by value, and the assignment semantics are such that a.b.foo is now bound to a new location which has the value 100. So the way I think about it is actually by thinking about it under the hood. It's all pointers, so it's passed by value with pointers everywhere, and they just don't ever let you have access to any of the pointers. So that's how I like to think about it. So you can never change something that calls you because you can't get to that raw pointer to change it, because it's passed by value. But you can change fields just like you can change structs, fields of a struct when you pass a pointer to a struct into a function. So the output was 42.10, correct? Yes. I meant to put that on here. Questions on this? So this is kind of showing how murky things can get. We started thinking about different languages and different types of semantics. Okay. So now I want to take some time since we're at this really cool low level talking about code and how it's implemented. So this is something that I really want to do because of my security background because we've been like touching this issue almost, and so I just want to cover this so you can say, yes, I learned about this and I know exactly how this thing works. So some of the implications of, so what's seeddeckle? Yeah, the x86 Linux calling convention. So it's a calling convention for x86 processors of how to call functions. So what's stored on the stack when we call a function? The base pointer? Return what? Return address, which is what? Yeah, the next instruction to be executed when that function returns. So those are both saved on the stack, right? So you're a program, you're running an x86, you're running on Linux. What memory can you read and write to? A high level. Any allocated memory? Yeah. So pretty much anything. You can at least try. You can try to write or read from any memory. You can definitely read or write to any allocated memory. So what prevents a function or a program from changing those values on the stack? Nothing. Nothing, right? Nothing. There's nothing, there's no protection. It's just, what is it to the compiler, to the processor, it's all just memory. Right? So what would happen if a function did and changed one of those values? Changed. What was it? You would have, what? A suite? Weird way to think about it. Yeah, so if we could so can we write to the stack as a program? How do you know that? Because that's what the program's doing, right? It's pushing values onto the stack. It's writing to that memory. So clearly our program has permissions to read and write to that stack. So what would happen? Where the instruction pointer is? It would probably just terminate, why? Yeah, what is it zero memory? So yeah, when it gets to the return instruction, right? Where it pops a value off the stack sets the instruction pointer to that. Does the processor know that you didn't actually come from zero? No, it just knows, hey, I'm supposed to take that value off the stack and start executing at it. Doesn't. So when I say that you can read and write everywhere your program, so basically the OS tricks your program to think that it has all access to the entire memory. So you can try reading and writing it everywhere. Whether that's been allocated or deallocated, that makes a difference. So that's how virtual memory in the operating system means that your program thinks it has the entire address space. So you don't, so there's actually no way that a program can access the operating system memory because it doesn't, it literally can't even ask for that address because it only sees everything that's all in its process space. Okay, let's look through an example. So this is kind of, we're exploring this question of what would happen if these values change during program execution? Okay. So we have a function very similar to what we looked at before. So if you've kind of already done this I will kind of briefly go over this or I'll go through it a little bit faster than I have before. So please, definitely ask questions. So here we have a function, my copy that takes in a string pointer. It has a local buffer called foo and how many, how much space is there for foo? Four bytes? How do you know four? Because there's a four there. Yeah, because there's a four here, right? This is how we specify. So we're basically saying I want where is, and where is foo stored? On the stack. On the stack, why? It's a local variable. It's a local variable, right? It's not global. So it has to be stored on the stack. Okay, now we're going to string copy string into foo. So what are the semantics of this string copy function? Right, so copy so it's string copy destination source. So take string take a byte, the first byte of string copy it to the first byte of wherever foo points anchor in both of them and keep doing that until string points to its null byte a zero. And you keep doing that and keep copy it. All right, and then just return. So our main function we're going to call calle and we're going to pass it an awesome string about csc340 being the best class you've ever taken and that rocks. Then we're going to printf after, so we're going to just print something else and then we're going to return zero. So is this a valid c-program? Oh, that's right. I changed the name of my copy because I wanted it to be not the same as the last one. So yeah, change this to my copy and then do we have a valid function? Yes. Okay, awesome. Good eye. I'll make a little note. This is what I'm programming on. Powerpoint is a lot easier. Okay, so this code compiles to x86 code that we've seen. So we first have the main function which does pushEVP, move the stack pointer into EVP, subtract 16 bytes from the stack pointer. What is this called in the function? Prolog. The prolog, everything that happens in the function before hit. Then we're moving some value onto the stack pointer and calling my copy. So what is this value? It's the instruction pointer. It's the address. So it's on the stack as the first thing that we pass to my copy. So what are the semantics of passing values onto the stack? So we push from right to left the values onto the stack. But there's only one parameter here. If this is the value on the stack and this is the parameter, what must this value be? A pointer to this string. So the compiler said, oh, there's a constant string here. Let's just put this at some memory location. It just decides there. And then it says, okay, now I'm going to push this address onto the stack because we're passing in a car star. And what's inside of a car star? What's the value? We're going to draw the box circle diagram for a car star. What would the value of it be? An address. An address of some string. Okay. Then we're going to move another value into eax, move eax onto the stack pointer and call printf. So then what must be in this value? Huh? Another string. What is that string? Yeah. After, right? The string after. Okay. So we don't know what these values are, right? But the compiler knows. It created global memory for these. And so it can pass these functions here. We move zero into eax, call leave and call return. What's the zero in eax? The return value. The return value of what? Of main. Okay. Let's look at the myCopy function. So we push evp, move the stack pointer to ESB. We subtract 28 from the stack pointer. We move evp plus 8 into eax. What's evp plus 8? So 8 is up or down on the stack. Up. So let's see what it's doing with eax. So then it moves eax into esp plus 4. It takes evp minus c and puts it into eax. Then it moves eax onto the stack. And then it calls string copy. So maybe let's step through this to kind of see what happens. Then it calls leave and calls return. Okay. So let's, yeah. Which one? Say that. Yes. So it takes evp and adds 8 to it. And then moves, take whatever's in there and move it into eax. And then take whatever's in eax, which is what we just moved, and move it into esp plus 4. So the stack pointer plus 4. And then take what's in, take evp minus c from it and take that value and put it in eax. And then move eax onto the stack pointer and then call string copy. So let's step through this. Okay. So here we have our registers. This time we only need to care about 4 registers. We have a bunch of assembly on the right. And we have a stack that's going to get surprisingly large. Okay. We'll just keep it at a previous value that we already had the stack at. So the stack pointer we know is fd2d4. Because I say it is. And the base pointer is something, but what do we know that the base pointer has to be? Yeah. The location of the frame pointer of the previous frame. So what do we know about it in relation to the stack pointer? It's got to be above it. It's got to be above it, right? So that was the problem we had last time. So I believe this is above it, right? It's higher? Good. Okay. I definitely made that. All right. And so we say that the instruction pointer is fd2d4. Okay. So now we're going to kind of step through this. If you have questions, feel free, raise your hands. You guys know the drill. Okay. So we're going to push evp onto the stack because we want to save whoever called us our callers evp, right? Because we need to use evp as our frame pointer for function making. So we're going to push evp so we're going to move the stack, the current stack pointer into evp setting our base pointer as where the stack pointer is now. Then we're going to subtract 16 bytes from the current stack pointer. That's 10x. So that's going to move the stack pointer down. Then we're going to move this constant value whatever, some crazy constant value onto the stack pointer, which is right here. And then we're going to call myCopy. So when we call myCopy, what happens? It stores the next address. What's the next address? 423. Yeah. So it's going to push the next address to be executed onto the stack. So here we push 8048423 onto the stack and the current stack pointer is pointing at fd2pc. Okay. Everything is pretty normal, right? Yeah. Okay. Now we're going to push evp onto the stack to save main's base pointer. Right? We're going to move the stack pointer into evp. So now we're setting our base pointer right now where the stack pointer is. And then we have to subtract 28x from ESB, which is, I believe, 40 I believe it's 40 in decimal. So that's 10 things I had to make room for. So everything got a little bit smaller. If you have questions speak up. Okay. So we move the stack pointer all the way down. But the base pointer is still pointing at the top where the stack pointer was, right? So we just allocated some local space for our function by moving the stack pointer down. So now it's evp plus 8. So we talk about this. What's evp plus 8? What was it? Yeah. The location to that string that we passed into call e. So we're going to take that. We're going to put it in eax and then we're going to take what's in eax and move it onto the stack plus 4. Okay. Next we're going to take the base pointer evp minus c. So it's evp minus c. So what do we know about references from the base pointer? So we know if they're greater, if they're added then what does that mean? That's definitely what it means. What does it mean semantically? What is that to the function? What was that? Parameters. Yeah, they're parameters to the function. Right? What about negative from the base pointer? Local variables. We're going to address evp minus c. Which local variable? How many local variables does my copy have? One. So foo. Right? So that's the location of foo is at evp minus c. So we're going to take evp we subtract 12 from it or c. We're going to move that into eax and then we're going to move eax onto the stack pointer. Right? And then we're about to call the function string copy. So now what are the values that were what are the parameters that were passing the string copy? Yeah, foo and string str which is the parameter to call the, or to my copy. So here, so, right? And this makes sense, right? So where is foo? What's the address of foo? It's right here. It's fd2ac. Right? We calculated it. It's at evp minus c. And we know the address of the parameter string because that was passed into us. Right? So we know that that comes from up here which is what got passed into us. So now it's what string copy going to do. Yeah, so it's going to say hey, whatever's at 804 8504, if that's not a zero copy whatever that byte is to wherever fd2ac increment both numbers by one. So we move up one more byte and we keep doing that. So copy copy copy copy So when we increment fd2ac, which direction is that going to go? It's going to go up, right? So when we copy that string, we copy increment copy increment copy increment we're going to copy up the string. How many bytes is there between us and how many bytes do we say that foo could hold? Four. So the compiler looks like generously gave us a little extra space and a little extra breathing around the stack. How much space is there between us and let's say something important? 16? Yeah, 1, 2, well it depends on how we count. Yeah, I think it's 3 boxes. So 12 bytes in between us and what's this fd2d0? Was it? The stack. Was it semantic? Where'd it come from? It's what? It's not the return almost. Yeah, it's main spring pointer, exactly. So the first thing that we did was we pushed evp on the stack right here. And that's where this value came from. So then what's above that? The next address the address of the next instruction that we're going to start executing from when we return. Awesome. Okay, so we call string copy So now is our stack look like? Does it look like this? Nope. Alright, we need to know where our string is, right? So this our string, right? There's a 0 at the end but these are just the sequence of bytes. So these values whatever the hex values are, these are represented in the string. String copy takes that so it takes at fd2ac so it copies asuspace those 4 bytes into fd2ac so it looks like asuspace and it's a little weirdness. What's 20 in ASCII? Let me know if it's up ahead. Space. So why is it 20, 75, 73, 61? What's 61? Hey little endian. Yeah, so architecture, endianness of integers, right? Which is the least significant byte and the most significant byte? So here xA6 is little endian so even though we write the bytes out from fd2ac, fd2ac plus 1 which is fd2a e and then fd2 b0 Yeah, all the way up. When you look at that and you look at it as an integer, this is what it looks like. The integer of whatever hex 20, 75, 73, 61. But does the copy function stop after copying these 4 characters? No. When does it stop? What end? The string terminates and which string? The value that is passed The value that is passed is the second parameter so in this case 804, 8504 right, this string so it's going to keep copying until the end here So the next 4 bytes are going to be cse space and is it done? No. No, it's going to do 340 space Is it done yet? No. Oh, it's going to do fall and then it's going to do space 201 and then it's going to do 5 space RO and then it's going to do cks exclamation point and then it's going to write out a 0 right after this but I didn't want to it didn't line up perfectly so I didn't want to include it So what happened to our stack? Clobbered So is my program going to stop? No. No, right? It's returned string copy said hey I did what you wanted me to do I took one string I copied it into the location you gave me and now it's returned to you All right, leave It's a reverse of this so it's going to set the stack pointer to the current base pointer and popEVP So what's the value that's going to be in EVP? This one here? So if you do popEVP here I'm just going to take whatever that value is copy it, put it in EVP because that's all that these functions know how to do. They just take the value off the stack and put it in there Okay, now like return so this mandates up return Take that value that's currently on the stack put it in the instruction pointer and start executing there right? So can I start executing at 3131313220? Probably not because there's probably no code there, right? So what am I going to get? Segmentation fault Segmentation fault, right? Because I tried to access memory that has not been allocated to my program so that's going to give me a segmentation fault So and you can run this, you can test this in GCC, you can run you can run it it'll give you a segment fault if you put it in GDB to debug it you can run it and it'll say, hey I'm starting this program everything's awesome and then it goes, oh no I got a segment fault here because I tried to execute this memory I tried to I tried to access this memory location that doesn't exist to try to execute stuff and if you look at the registers here you can see that the EVP, we changed the value of EVP because we erased the save base pointer and we changed the stack pointer the instruction pointer to be whatever we wanted Okay, so so why is this a problem? Why is this a security problem? Because you can access memory that you aren't supposed to be able to access You can access, so yeah I could get your program to crash Do I really care about crashing your program? No Maybe, it depends on what it is, right? If it's going to give me a million dollars if I crash it then I want to crash it Yeah, so what if I so I can control the instruction pointer that means I can control where your program goes to start executing so if I can get it to start executing something I want then it'll start interpreting my data that I gave your program as code and start executing my code which means I'm running an editorial process and I can do anything your process can do So this is one of the most common vulnerabilities in C and C++ So I really want to show this to you guys since we already talked about the base pointer and the EIT because it's really cool and very important Anyways, thanks for listening See you guys on Monday, Wednesday