 We started today. Last week of the semester. Are we excited? No. How are you guys excited? Because I'm not going to have you as a teacher. Well, depending on how you do in this class. Generally, not you particularly. Just generally. I'm too busy being terrified to be excited. Too busy being terrified. Two more weeks it's all going to be over, right? So you did a workshop Thursday? I had probability class. Is there anything else? Yeah, actually, you recorded it. I'll put it online soon. I just haven't done it yet. I'll put it on YouTube. I recorded it just like this. Some of the stuff on there, you don't actually have access to the server because I have taken it down. Yeah, giving random students access to servers in my lab is not like a great long term strategy, but yeah, it'll be up there and all the content will be up there. I think I'll probably put the slides on there too. That should be pretty easy. Yeah, if you're interested in that kind of stuff just let me know. Cool. Alright, project five do Friday, right? Is it Friday? It's on the website. I don't know, you can't force mind control me to give you a different day. Alright, let's see midterm and just midterm threes. So now we're back to our old friend Landicatulus. So, why are we talking about Landicatulus? I know it's kind of early to ask this question. Do you want to know when Nathan is going to be crazy? I don't know. I'm not going to promise anything until it'll be before your final grades are released. I can guarantee you that. That's a fact. What if I tell you, well, you guys should just assume that you should study really hard for the final, right? That's what I want out of that. Just tell us we all failed it. It's good. And we're all going to have to work hard just to... Ah, it's fine. I don't think you guys failed it. Actually, my money is on you did better than on midterm two and midterm one is my guess. We'll see. I will give you one more homework on Landicatulus because Landicatulus will be on there. But pretty much everything that I have tested on in the past has been on either a homework or a practice midterm. So I feel like you have all the study material you need basically up to the final. So it's basically going to be through Landicatulus, beta reduction, and the final will be comprehensive. Anything that we've talked about in class up to this point is fair game for the final. Okay, so why are we talking about Landicatulus? Since it's been, it gets on the curriculum and we have to part of it. But if we're just doing that, I would just go, oh, Landicatulus is a thing and then we put it on, right? Well, it's like a formalized way to describe how programming languages work. Yeah. So it gives us a formal definition to think about programming languages, right? And it gives us we've already studied Turing machines, right? And so we can relate and actually see that, wow, this completely different paradigm of a machine or computation actually have the same expressive power as a Turing machine. So that's why I think it's really cool. So we've been talking about Turing machines. Landicatulus, I hope that you've gotten familiar with the syntax and disambiguation, right? That was on the midterm and on the midterm practice. So that would be good to study. So now we can get into really the semantics. So we talked about combinators. So what's a combinator? Something, an expression, yeah, that has no free variables, exactly. So any expression that has no free variables is considered a combinator. And this is a definition we're going to use now that we're going to talk about in the future. So bound variable. So I think this is also a review, right? So we went over this on Monday, right? So basically, you can think of it in two ways. A, it's the opposite of a free variable, right? So it's a free variable. Yeah, it's okay. There you go. Yes. Right? So the variable's not free, it's bound. And if it's bound, then it's free. Or it's not bound, then it's free, right? But the question we always want to ask is specifically the bound variables, right? With free variables, free variables have no enclosing abstraction. For bound variables, we want to know not just are they bound or are they not bound, but what's the scope? So what is, which abstraction bounds that meta variable? Okay, so we need to go into the formalisms to describe exactly what bound variables means. Okay, so if an occurrence of x is free in some expression e, then it is bound by lambda x in lambda x dot e, right? So if we look inside the body of an abstraction, we say just looking in here, it's a free variable. That means that if we put a lambda x around it, put some abstraction around it, then that means that that variable x is bound by that specific abstraction. If an occurrence of x is bound by a particular lambda x in expression, then x is bound by the same lambda x in lambda z dot expression. So the idea here is that by, so basically these are defining our scoping rules. So this says, hey, if it's bound already in e, then just adding more abstractions on the end is not going to change what it's being bound as, right? You can't change it by adding more abstractions higher. You can only change it by adding more abstractions kind of lower down. And that would be the same if that lambda z dot expression was lambda x dot x. Exactly, yes. That z could be anything. Yeah, so it could be a lambda x. Right? Even if z is equal to x. So lambda x dot lambda x dot x, right? So which lambda expression, I'm going to give you the numbers, one or two binds x. Two. Two. That makes sense. We look at the inner body, right? And we see, okay, x is x free here in this inner body in the very inner body inside here. Just look at this. Is x free? Yes. And so we know by this first rule, okay, lambda x dot where x is free, that means x is bound to this abstraction. That's what this first rule tells us. And the second rule says it doesn't matter how many lambda x's we put on in the outer outside, right? It's going to be bound to this lambda x, this abstraction that it's originally bound to. This kind of does our scoping rules as like the closest, tightest bound possible. And we have to go through kind of all the cases, right? So if the occurrence of x is bound by a particular lambda x in expression one, then that occurrence in expression one is tied by the same abstraction lambda x in expression one, expression two, and expression two, expression one. This just says you can do, application doesn't change the binding, right? It doesn't matter what happens in any of the applications in the left side or the right side of an application. Bound things are still bound. Questions? So some examples? So now here, what binds... What is this x bound to? The first lambda x. What about this x? The same lambda x. Yeah, exactly. What about this x? Also the same. Also the same. What about this x? It's free. It's free variable, yes. This y, bound here. Yeah, the first y, the z. Free. Free. This y. Bound this y? Free. Exactly, right? So these bind all here. The italicized y is all bind. And x and y are both free here. Cool. So here, okay, this x is bound where? The first lambda x. The y is bound also to the lambda x. This x is free. And z is bound here. Let's see. What about this? So what is this x bound to? The first x. The first x. What about this x? No, the second x. So this inner x more tightly binds this x. Think about scoping, right? This is like an outer declaration of some variable x, like maybe a global. It's not really a global declaration here. This is some inner local variable x, which shadows that outer x. Okay, cool. So why don't you think about this question. What does it mean for two functions to be equivalent? What does that mean? How could you do it? How would you... There are inner expressions. More generally, like I said. The bound variables and the free variables are the same. Like the ones that we were italicizing and folding and underlining, those were the same for two different expressions. Okay. Why wouldn't we just say they have to be... So are two functions that are textually identical that have the exact same string? Are those going to be functionally equivalent? If both of their variables are the same. Yeah, the exact same text. How do you know the operations? What operations? How do you name operations with that context? They have to be textually the same and their free variables have to be the same. So they're textually the same, right? So like the exact same string. So if we have a function foo, that's some body, I don't know, x plus y. Just generally not thinking about Landon calculus, right? x plus y. Then we have a function bar that also does x plus y. Are those equivalent functions? Yeah. Sorry, I wasn't going to answer that. Okay. I was thinking about my question. Once you look at it just like what we were doing before is structurally equivalent, would you look at it like that? Yeah, you could look at it like that, right? So if they're name equivalent, name equivalent and functions, right? Yes, functions of the same name are the same, right? But what if you have two functions, foo and bar, foo returns x plus y, bar returns x plus y? They're functionally equivalent, but they're not name equivalent. Are they textually body equivalent, maybe? They have the same body, x plus y? Body, yeah. They have to be in the same scope. In the same scope? Yeah, why? Well, because x can represent different things in different scopes. Right, I think that goes to the point of here, right? Is it depends if this x and y, if there's some global variables or maybe there are other, you know, what do these x and y refer to, right? So let's take parameters, if they're both parameters, x and y, and they return x plus y, are they the same function? So we have a function foo, takes in parameters x and y, and returns x plus y. We have function bar that takes in, I'm not going to give them types, but are these functionally equivalent? Equivalent functions? Yes. Are they untyped? Yes. What if they're, okay, what if they're tight in the same type? Yes. Yeah? What about this? I get rid of this, and I say bar, is that, are they the same? Are they textual? I mean, if you look at the text of the body of the function, are they the same? No, but they still do the same function. Why? I think they're the same. Because of the plus operator? I think they're the same, because variables, they're just two variables, they're not constrained to a certain type. So I think they're still the same. Even if they were, so let's give them all ints, say they're all ints, x, w, y, and z are all ints. Even if they're either untyped or all their types are the same, then both, those both are the same functions, because you use the same operations to evaluate the function. Is that right? The function is evaluated exactly the same. Yeah? Well, if you were setting the value of the return for that into another variable, the output, if the output for them is the same regardless, then they're equivalent. There's no way to define that, just based on generic information. I don't think you need more information depending on what kind of influence you're trying to define. Yeah, so well, let's think of it in a couple of ways. Could I use, everywhere I was using foo? Could I substitute it for a bar? Is it going to change my program? No. Why? Because it does the same thing. It simply combines two values. Yeah, the evaluation is exactly the same. Yeah. It doesn't, it depends on if you're doing like pass by value or that sort of stuff. Does it? You tell me. I mean, yeah, they're just copies of what you're passing into it. Well, if it's pass by reference or pass by name, does it matter? What are their names? It doesn't matter what you put in them. They're just there for understanding what's going on. It won't matter what the names are. Because you're putting in different names in them anyway. What about this one? It is also pass. That would be different. It's just the same because of how, you know, addition to work. Yes. Right? You look at this and you know, you have the equality right? Well, a plus b is equal to b plus a, right? You know this to be true. But if we just look at the functions, right? Assuming no knowledge of plus, are these the same? No, right? Because they're doing different things. Even if I change this to be x and y, this is going to be different than both of these. But these would, I would argue are functionally equivalent, right? You could use one for the other in here. And it would work just fine. So, was this, are these two expressions functionally equivalent? Yes. Yes. Because they're just declaring. It's just self-referencing. Right. So it's a lambda expression that, well. That returns. So why? So talking about lambda expressions, right? What do we know about this expression? How could we try to actually determine using what we know that these are the same? Well, the variables are both bound in the same, not the same. Like they're bound in the same way. The inputs and the outputs are the same. The operation is the same because we don't know what any of the variables are. But they're both expressions that simply bind a variable to a meta-variable. Yeah, so let's talk about this. Could we completely, so does it matter that we call this meta-variable x and this meta-variable y? No. Just like we write a function, does it actually matter what names we give to our parameters? No. No, right? And so the idea is, well, if we can rewrite our function such that we change all of the parameter names, or here the meta-variables, if we change those and we get another function we'll say that those are functionally equivalent, right? What about something like this? It's not equivalent. This is the same? Yeah, it's defined a variable to a meta-variable while containing a free variable. Doesn't it matter if they're in different order? It doesn't matter that they're in different order. I don't know. Why? No, because the bound variable is the first one. No, they're still equivalent. Very equivalent. Yeah, because it's given an input apply. We're going to return the same output? No, no, no. It's just a function which, given an input, applies another function to the input. Let's pick what we talked about with the addition, right? Could you use one in relation to the other? And you'll get exactly the same output given the same input. Okay, so the free variable, because the free variable is not found by this function, it can be different anytime you call it. Is it the same free variable in each function? Not necessarily. So does that maybe change possibly the semantics of what this function does? Normal kind of example, right? If we had... What's the scope of this variable X? Yeah, we don't know, right? Some global variable, right? What's the scope of this variable A? So are these functionally equivalent? Could you use one or use another? No. Why? Because we don't know what the scope of A is. In regards to bar. This could be a function inside of... So even if we had this... We still couldn't because in A and X might not be the same thing, so passing in a value wouldn't actually return the same thing. Right, so if I give it the same input, right? Because I'm not going to get the same output for each of these programs, each of these functions. No. Why? Because A and X are not the same, so... Right, the global A and X, right? They're each referring to global variables, or variables outside the scope free variables, right? And so it depends on the context of when we execute this function, what those global variables are. But if you write exactly like this, though, they are functionally equivalent, right? I mean, I know that X can be anything and A can be anything. But we're going to get the same output for the same input given the state of the system. What if I have later on I have X is 10 and A is negative 10? Then I call, I don't know, foo5 and bar5, right? Are these going to give me the same output? Because it depends on what these global... what the global state is, right? We can think of it in Lampti this term, X and A are both free variables here, right? We don't know what they mean. They could be anything, right? But now, what if I change this of these functionally equivalent? The same free variable, right? Yes. It's not the fact that they're relying on global variables. It's the fact that they're actually relying on completely different global variables, right? Where as here, yes, no matter what I pass in A or B, right, this will each of these invocations will return me the exact same result. So they're functionally equivalent here. It is the exact same thing. Okay, so we're going to formally define what we mean by equivalence and we're going to call it alpha equivalence. Well, somebody else called it alpha equivalence and we're going to use that name. The idea is alpha equivalence is when two functions vary only by the names of the bound variables, right? Which kind of matches our intuition. If we have functions, we change the bound variable names, right? We can change it to anything we want and almost anything we want and we'll get new behavior. When is the case that we could not... Yeah, exactly. So, for instance, could I write, so I'm going to claim that I can just write all of these new functions, right? Baz, C, whatever, right? Changing this bound variable. But can I write foobar? Can I write foobar x? No, because that overrides the global scoped variable. Right, what was a free variable is now bound to x, right? So, exactly. So this is...you can't just rewrite every bound variable, right? You have to have some rules on how to do that. Okay, so how do we do this? So we set it to expression. Expression one is alpha equivalent to expression two, but we need some way to remain variables in an expression, right? We need some way to actually...some operator to do that. And actually what we're going to build up, this operator is going to...we're going to use this to do function applications. So this will help us in learning about that. Can we do a simple find and replace? For instance, here can we rename, like, x to foo? Yeah, we could rename y to bar could we rename this y to x? Because it's changing the scope of the inner... Yeah, it's changing the scope of the inner x, right? Is this x free? No, but is it free in the body of this abstraction? Yes, so that's y, right? That is why we can't rename this variable y to x because there is a free x inside the body of that abstraction. Okay, and then we can't just rename x to z, y. We have a free z, exactly. That's going to mess things up. Okay, so we're a renaming operator. We're going to use this syntax. We're going to say e curly brace yx, which means we're going to replace the y's with the x's. So this is pretty simple. So we have to...we have our cases, right? So we say, okay, for an expression to evaluate this operator for an expression, we need all the different cases. So here we have x of y replaced with x. I guess I just got that backwards. We're replacing x with y. So we're renaming x to be y. So if the expression is just x, the result is y, right? Seems pretty straightforward. Applying this operator to another id, let's say z, where z is not the same as x. Then it just returns z. So the left side is replaced by the right side of the... So the first one is backwards. So the first one is backwards. The way they're reading this is replace all y's with x's. It's the other way around. It's replace all x's with y's. And so the idea here is this is an operator. We're applying this operator to an expression. So we have our cases. We know an expression can be either an id, an application, or an abstraction, like an abstraction and parentheses. So this is what we're defining here. So here, does this case take care of all id's? Every id is going to be in either one of these two cases. Expression can be an id. Is that correct? In our parsing rule, expression can be an id. If it's an id, it's either going to be equal to x, in which case this rule applies. Or if it's not equal to x, this case will apply. Does that take care of every possible id? No, we also need to account for a name that belongs to a free variable. So we're actually building up an even more basic building block first. So we're first going to build just a formal operator to do renaming. And then we're going to use another substitution operator to actually do the proper substitution. So we first need this, but we're just defining an operator. So we're saying replace all x's with y's. Great. If I see an x, I know I should replace it with a y. I know I have something that's not an x, so I leave it as is. I don't change it. And that covers all of my id cases. Something is either equal to x or it's not equal to x. Those are the only cases. Then we have the case of application. And it's pretty easy. Basically this just means nothing happening. We apply our operator to the left side and the right side. There's nothing special. Nothing special happens. We just say, okay, if we have an application, that means we apply this operator to the left side and apply this operator to the right side. What's the other case? Yeah, lambda. And so we have two cases here. If the meta variable is the variable we're interested in. So here we're replacing the meta variable x with y. And then we call, we pass the operator, we apply the operator into the body of the abstraction. This is a very simple, stupid renaming operator that's just doing basically the find and replace renaming. So the other case here is if the meta variable is not equal to x, then we don't change that, but we do apply the operator inside. Any questions? Very simple, very stupid, just renaming operation. So if we do something like this and we say we're applying the renaming operator, we want to rename x to foo. So the first step of this operator is going to, that last rule is going to, well the second to last rule will apply. We will replace the meta variable x with foo. And then we will apply this operator to the body. The body here is x. We see x, we're going to replace it with foo. Pretty good. We got more complicated examples. We're going to replace all x's with bars here. So this outer is what? What type of expression is this, the outer one? Application. Application, right? We have, actually it's an ambiguous one, right? We have this guy here, this whole thing here, and then an x and then a y. So we can actually just, we know the rule, we can actually just distribute this across the x. Across the left one this thing, the x and the y. Right? So we just say, okay the only thing we do is we apply that to every part of the application, right? Nothing special there. Then we can just choose which order we evaluate these things in, right? There's no, nothing that says we have to do them in any specific order. So we can evaluate the right one and say this is just y, renaming x to bar of y is just y. We can do this x here, renaming x from bar to y is bar. Now we're here, now we're at the lambda, right? So now we need to replace the lambda x, the outer lambda x with bar and then apply this operator to the inside, to the body. And then once again we're going to do this again. We're just going to replace this bar with this x with bar and then this is going to happen again on the inside and then we're going to find and replace that x in the middle with bar. Super simple. That's the facility to find and replace. Okay, so for alpha equivalence we're actually still having to find the alpha equivalence, what we actually want to have happen here. So the idea is basically we're going to find what it means for things to be alpha equivalent. So the idea is for all expressions, any expressions you want and any variable that does not occur in that expression, this is defining lambda x dot e is alpha equivalent to lambda y dot e replacing y with x with y. So what does this actually mean? So what does it for all expressions e mean? Yeah, just any lambda expression. Here you can think about it, we're actually interested in talking about if two functions are equivalent. So you can think about it as the body. So if you're interested in a particular function talking about the body, but any expression e, so give me a random any kind of lambda expression you want. And all the variables that do not occur in e, so what does this mean? That do not occur in e. Actually it's even more broad. Any variable, all the y's are anything that is not free and not bound that doesn't even appear in e. And then we're saying that if you have some lambda x dot e, then you can replace in your original expression, you can replace every instance of x with some new variable that does not appear in e. The new thing y, and it's going to be alpha equivalent. So why can we do this operator here? Why can we do this e x replaced with y here? Yes, but why? You're replacing the bound variable in the initial expression with another bound variable and that's what alpha equivalent is by definition. Exactly. But the important thing that we're doing here is that we're putting conditions on what we can change things to. We're not saying we can change why can't be any arbitrary variable because we saw that that actually can cause problems. What does y have to be? Something that's not in e in the body exactly. That's why you can do this renaming operation on e because you know why this does not appear. There are no bound variables called y, there's no free variables called y. This is why that you can do this operation and not worry about things that are bound or not bound or renaming. Let's think about it like this. Are these alpha equivalent? I heard some yeses. We actually think we already said yes, they are alpha equivalent. Can we actually use this to show that they're alpha equivalent? If you please. So what would be the e in this case? x. It could be either one you want to do it. If we're keeping exactly with this way, we could do just y. e is the inside of this. We can take y and does x occur inside the expression that's just y? No. This means then we can put a lambda y dot y on the outside and then we can have over here a lambda x dot and then replace all y's with x. Now we know that those are both alpha equivalent. What about something like this? No, why not? There are free variables that are not the same. This one? Yeah, w and z. Exactly. We can't change those free variables. This is what they're saying. The only things we can possibly change are the bound variables. The key problem is this w and the z here. These are free variables that are getting changed. These are not alpha equivalent. Would you make something that is alpha equivalent to this? Absolutely. Renaming operator was incredibly simple. It's just replacing one variable name with another. Remember, we tried to get some intuition for function applications here. When we did something like this, we had lambda x dot plus x1. We reduced that when we were doing our reductions, just like the examples we replaced that with plus one two. What did that actually do? It substituted x for two. Application means take the meta variable, replace all instances of that meta variable, but remember when we talked about the bound rules, do we want to replace every single possible x in there with two? No. We only want to replace those x's that are actually bound to this meta variable. Anything inside we shouldn't be touching. It's essentially parameter passing. We're passing in two for x. We need to replace everything that refers to this x with two in this case. We can't use renaming because renaming is stupid and just renames everything. Simple. This is why we're going to use another operator which we're going to call substitution that's going to be a little bit more intelligent. It's going to actually be able to change only the bound variables inside here. What we're going to do, we're going to use this syntax. Our substitution operator is e square brackets this time. x goes to n where e and n are lambda expressions and x is a name. This is the operator that we're going to build and we're going to use this to show how this actually just does function computations and function calls. Questions on why we need a substitution operator? The substitution operator just replaces anything. This n is an arbitrary lambda expression. That's another difference whereas the renaming operator was we could rename an ID for an ID. Here we need to substitute x for some lambda expression n. In our function application here, this could be expression space expression. This on the right can be an arbitrary lambda expression. We want to be able to substitute that in for x. Some arbitrary expression. The renaming was bad because we could only use 98. Yeah, that's part of it. Exactly. Part of it we can only rename to another ID. We can't say this ID is actually lambda x dot x. The second reason is because of the bound variables. The renaming operation just renames everything and doesn't, with this substitution operator, we only want to replace or substitute for those x's that are bound to this x. We're going to define this actually seems pretty easy. I've already solved this. We want to replace some x with 2 in this plus x2. This should be what? Yeah, plus 2, 1. What about something like this? A, first question, should we replace this x with a 2? It can be any arbitrary expression. This 2 could be lambda x dot x. A, we can't have this expression here as a meta variable. B, what is this x bound to? This x. What is this x bound to? Nothing, it's free. Then should we replace this x with 2? What about this? Again, remember we don't have a plus operator. Don't worry, we'll get there. If I had this, I applied 2 to it. What is this return? lambda x dot plus x, yeah, plus x1. Here I'm replacing every instance of this lambda x with the expression 2. How many instances of this meta variable x are there in here? What does this x refer to when it's bound? The inner lambda x. When we're applying this for the outer lambda we only want to replace all instances that refer to this x with 2. Just like if we were just to do lambda x dot plus x1, apply that to 2. We need to replace every instance of this meta variable x inside the body which is here with a 2. We're going to replace this x so this is how we get plus 2, 1. If we look at it from a substitution operator, essentially what we're doing is we're taking the body the body here is plus x1 and we're substituting x for some expression 2. This should return plus 2, 1. Here when we do this application, essentially what we're saying is lambda x dot plus x1 sorry the spaces, not plus x1 and all the terrible limitations of real paper. With a substitution operator, apply and replace x with 2. What should this return? What was this? Lambda x dot plus 2, 1? What happened? Why did we replace this? This x, but here when we tried to do this application just by looking at this application what do we want to get? Lambda x dot plus x1. This is a function that takes in an x that returns a function that takes in an x that does plus x1. Eventually we want to try to use the substitution operator to do to formally define exactly what we mean when we do this application process to make it more formal so we know exactly what happens. Informally what this means is we want to replace this x and we want to replace all instances of this x with 2. Inside of its body we want to replace all x's with 2. But this x does not refer to the same outer x. It refers to this inner x here. We do the substitution operator here and another way to think about it is we're kind of saying we want to replace all free x's with 2. If we want to replace all free x's with 2 in here then what would the result be? Plus x1 which then is exactly what we wanted to get from doing this application. And the same thing if we use that same logic here replace the free x in here with 2 do we get the same thing? Plus 2, 1. That only implies the free variables. Like we said earlier, it only implies the things that we're not using the expression for. Yes, because let's think about it like this. So we have some lambda expression, lambda x dot x, lambda x dot like this. So all the x's inside here, the ones that refer to this x when I remove this outer lambda x the outer x is free and why is that outer x free now? Because it was bound to that other x and we got rid of it, right? So this x is bound to the outer lambda x and this x is bound to the inner lambda x. What happens when I get rid of this binding abstraction? The outer x is free and why is that outer x free now? Because it was bound to that other x and we got rid of it, right? So this is the idea is basically you kind of think about it if I get rid of a function, right? If you throw away a function and you just look in the body of that function every free variable in that function that refers to that same meta variable it's now free because you got rid of that lambda, that abstraction. What was a free variable is now not a free variable. So this x is free but once I put an abstraction of lambda x around it then I know that this x has to be bound to that abstraction. So if I want to replace every x with let's say lambda y dot y I'm doing this function application, right? I want to replace every x with whatever this is, lambda y dot y. So what I can first do is remove the outer abstraction. So I'm left with lambda x, lambda x dot x and I'm saying inside here replace now every free x with lambda y dot y, right? So will this replace this inner x? No because it's not free exactly so it will be lambda y dot y. Yes, so this will be another application and then if I do this again then what happens? What is this application doing again? So here I applied this to this so now if I apply this to this what happens? Oh, so it'll take away the lambda y which will leave you with y and then it'll replace y with lambda. It just didn't function application. Now there is, I just want to go over really quickly there is one tricky case that's going to come into play when I have lambda x, I have lambda y, x, y and this applied to so I can have any arbitrary expression here. So doing what we just did we want to replace we want to get rid of the outer so we want to replace inside lambda y dot x, y we want to replace every free what? Every free x with y, z but what happens when I replace this y, z inside here? There's a new bound to y. Was y bound before here? No. So now I have this free y think about a global variable y here but I'm substituting it in for x here if I just did this substitution directly I'll have lambda y got y, z, y Is this y free? Is this z free? Was the y free before? And now it's bound which is a huge problem we've changed the semantics of what we're substituting in there Well, you wouldn't do that because of number one So going back to functional alpha equivalents what if I change all the bound y's here to w's Can I do that? It's still alpha equivalent Can I replace this x with y, z? Does anything happen? No, now I don't have a collision so I return lambda w dot y, z, w and now this y and z are still free like they were before and does it matter to functional equivalents that I change the name of this bound variable? No, not at all, right? Questions on this? I think this is a good before going into the formal definition of substitution I think this was a good way to go All right, cool, let's say