Transcript from the "Execution of Function Code" Lesson
>> Kyle Simpson: Now we need to turn our attention to executing the code. And to execute the code, we need a little bit more information that I glossed over in that first pass. There is some meta information that gets discovered as we go along, that is not entirely obvious as we go.
[00:00:18] And I skipped over it, but let's go back and fill in that meta information.
>> Kyle Simpson: There's something very important about where a variable shows up. Because where it shows up, the context in which it is used determines how it's going to behave at run time. Remember I said earlier that an identifier can only be in one of two positions.
[00:00:43] Either it's in a position where we're going to in some way shape a form, extract the value from the variable, or it's gonna be in the position where we're gonna put some value into the variable. Those are really the only two options, okay? And there's a special term for that.
[00:01:01] But the reason that's important is that we're gonna treat that differently at runtime. There'll be different validations on stuff depending on which position it's in. So that information was stored as the compiler was going through. In essence it kind of knew or it stored based upon some meta information.
[00:01:20] It knows for example that the foo on line 4 is on the left hand side of the equals as opposed to being on the right hand side of the equals. It knows what position it's in, and the position matters. If something is on the left hand side of an equals, it's gonna be the target of an assignment.
[00:01:42] If it's on the right hand side of an equals, it's gonna be the source of an assignment. It's gonna be the source value, okay? So in essence we have this question of is it in the left position or the right position? That's basically when a compiler theorist talks about it, one of the things they ask is what position is it in?
[00:02:02] There's different terms for this. I'm old school because I took computer science a long, long time ago. My professor called it LHS and RHS. LHS stands for left-hand side, RHS stands for?
>> Speaker 2: Right-hand side.
>> Kyle Simpson: Yeah, come on, right-hand side, right? Pretty easy. Left-hand side meaning it's the target on assignment, right-hand side meaning it's the source.
[00:02:29] Not always the source of an assignment, but definitely the source, okay? So it might be more helpful to think of target source versus left right, LHS, RHS. It's just my habit to call it LHS, RHS because that's what I learned way back in the day, okay? Some more modern terminology, they'll use L value and R value, or some other kinda.
[00:02:48] Whatever the terms are, you understand it's either the target or it's the source, okay? That's metadata that we need to store with that variable cuz we're gonna treat it differently depending on whether it's a target or a source. So that metadata is stored with the variable. Now, it's time to execute this code.
[00:03:05] And now that we're executing, there are no more var declarations, and there are no more function declarations. We handle that at compile time. Declarations are not a run time thing, we don't need to worry about them. All that's left is the executable code, and technically it's not even in source code for them anymore that we could read.
[00:03:22] We're gonna pretend that it's still written like this even though it's not actually, okay? So just pretend that the vars are all gone and the function headers are all gone and all that's left is the executable code.
>> Kyle Simpson: That's why I said earlier in our course, when we said var bar twice, the second one was a no op because the compiler came across that var bar, and he said, have you ever heard of the bar?
[00:03:47] And he's like yep, got him. Then it's a no op, I don't need to put another duplicate marble in the bucket. It's a no op. So by the time they run the code, the var bar doesn't exist anymore. Cuz it's already been handled, okay? So now we wanna execute this code.
[00:04:40] We're looking at line 1, there's no var there. But I do find a foo, and I find a foo in that target position, I find a foo in the LHS, the target position. And I need to figure out whether or not that variable exists. Cuz it might be that I'm using a variable that hasn't ever been declared, and that's an important detail.
[00:04:58] So I'm gonna need to have that same kind of back and forth conversation with the scope manager that the compiler had. That conversation is going to go like this, hey global scope, I've got an LHS reference for a variable called foo. Ever heard of it? That's again, one of those yeah/no questions.
[00:05:16] But there's even more new ones here. How many of you have ever played or seen the game Go Fish, the card game Go Fish. Anybody heard of that? Okay, so I've got young kids. I got a four year old and a six year old at home and I love playing Go Fish.
[00:05:28] My son, he's six, love playing Go Fish with him. He's almost at the point where he can hold his own cards, but he still kind of set them down and arrange them and stuff. And I have to like pretend that I'm not looking at his cards and I'm like, hey you got any eights?
[00:05:41] But what I love about the Go Fish game is it's just such a simple premise. I ask a question, do you have a foo variable? And there's only two answers, either yes here you go or what?
>> Speaker 2: Go fish.
>> Kyle Simpson: Go fish. Go look elsewhere. In the game of Go Fish, I gotta go to the deck to see if I can pull out the card I'm looking for.
[00:06:02] Here, the same premise applies. I am the engine and I am looking for the marble. I have a reference to this marble, but I need it. It's the scope manager's job to go tell me which bucket it's in and hand it to me, if it exists. So I'm saying, hey scope manager, hey global scope, I have this target value, this l value, this LHS foo, ever heard of them?
[00:06:24] And if he has, he's gotta go get me the marble, and if not, he's gotta tell me, nope, sorry, look elsewhere. What's the answer gonna be this time?
>> Speaker 3: Yes.
>> Kyle Simpson: Yes I have because at compiler time, we added a foo variable to that scope, we added the red marble, right?
[00:06:43] So the global scope manager is gonna get that red marble and hand it back to me. And now, I have a variable, I have a location in memory, I can go to the right hand side, find that value which is the quote bar, and I can make the assignment.
[00:06:55] Do you follow how that happened? It only happened because there was a formal declaration for me to discover. Had I been trying to do that and the answer had been no, a different end result would have occurred, okay? We'll get to that in a moment. Now we don't see any other part of this program executing the bar or the baz function.
[00:07:16] That's on purpose cuz I didn't wanna make things more complex. We don't see bar and baz being executed, so let's just pretend that some other part of this process executes them. Maybe they get executed as a click handler, or on a timer, or just in some other part of the program.
[00:07:31] Somebody calls the bar function. So let's execute the contents of var and we're gonna do it exactly the same as we did before. We're gonna start with this line 4. And on line 4, there is no var there, there's just a foo equals. So how's that conversation gonna start?
[00:07:49] Which scope are we talking to? A scope of bar, I have a what kind of reference?
>> Speaker 4: Well there is a bar though. What do you mean there's no-
>> Kyle Simpson: It's already been compiled away. We're executing, right?
>> Kyle Simpson: There's no bar, it's been compiled away. A scope of bar, I have a what kind of reference?
[00:08:11] I have an LHS reference, an L value, a target, whatever you're gonna call it, for foo. Ever heard of them and the answer is?
>> Speaker 2: Yes.
>> Kyle Simpson: Yes, because you declared him formally during the compilation step in this scope. Here is your marble. So now we have the marble.
[00:08:29] We go to the right hand side of line 4, we find quote baz that is an immediate value. We make the assignment, line 4 is complete. Have I lost anybody yet? Makes sense? All right, now sometime in the future somebody decides to execute the baz function. For now we're going to assume that they don't pass in any argument.
[00:08:52] Cuz there is a parameter that could receive an argument. Let's ignore the argument passing for now. Let's just assume they invoke the baz function, okay? We need to start executing with line 8. Line 8, how's it gonna execute. What scope are we talking to?
>> Speaker 2: Baz.
>> Kyle Simpson: Hey scope of baz.
[00:09:11] I have a what kind of reference for foo? I have LHS. An L value, a target reference for foo. Ever heard of him, the answer is?
>> Speaker 4: Yes.
>> Kyle Simpson: Why? Because of that foo perimeter on line 7, right? On line 7, you formally cleared it, so for all intents and purposes that's a variable that we have access to, we can assign to, okay?
[00:09:33] Great, so now I have my green marble. I've got my marble, and I go to the right hand side of quote bam. I assign quote bam into that variable, and we're done with line 8. We good so far? Now we finally come back to line 9. Which we skipped over essentially during the compilation.
[00:09:51] We didn't do anything with the scope of it. We did keep track of the fact that it was in an L value position, but we didn't do anything scopewise with it. And now we need to ask what's it gonna do at runtime? So that conversation needs to proceed exactly the same as before.
[00:10:11] So how does it go? A scope of?
>> Speaker 2: Baz.
>> Kyle Simpson: Baz, I have a
>> Speaker 2: LHS 4.
>> Kyle Simpson: LHS 4.
>> Speaker 2: Bam.
>> Kyle Simpson: Bam. Ever heard of him? And the answer is?
>> Speaker 2: Go fish.
>> Kyle Simpson: Go fish.
>> Speaker 2: [LAUGH]
>> Kyle Simpson: All right, because there is no bam declared in that scope.
[00:10:28] So now we need to understand what does go fish mean in terms of lexical slope. Lexical slopes are nested. So the default behavior then would be to say I'm gonna go up one level of scope and ask the question again. In this case that up one level is the global scope.
[00:10:47] So were gonna go up to the global scope and say, hey global scope I have?
>> Speaker 2: LHS-
>> Kyle Simpson: LHS for bam. Ever heard of him? And the answer is.
>> Speaker 2: Go fish.
>> Kyle Simpson: Okay, so we would look for the answer to be no or go fish. There is no where else to go, cuz the global scale is the end, right?
[00:11:34] Aren't I helpful? What? It just implicitly created a global at run time, because it couldn't find one formally declared. So now we have a global variable called bam. We have a red marble called bam that we get handed back. And when we make the assignment on line 9, we're assigning to a global variable called bam.
[00:11:58] You see that? Now that process that I just described where we implicitly create a global as a result of assigning to a variable that was never formally declared. That is virtually always a mistake.
>> Kyle Simpson: Let me say it this way, if you're doing that on purpose, stop doing that.
[00:12:24] That is never the right way to do it. Never, ever, ever should you code assuming that you will implicitly create a declaration in some global scope. That is a terrible idea. Yes?
>> Speaker 3: So is the process the same if it's LHS?
>> Kyle Simpson: We are talking about LHSs, are you saying if it's the same?
>> Speaker 3: RHSs.
>> Kyle Simpson: We're gonna get to RHS in a little bit, hold onto that question, okay? Right now we're talking about LHSs, and this undeclared LHS or unfulfilled LHS, as I like to call it, results in an implicit auto global. And that is a terrible, terrible thing. Okay, terrible for confusion.
[00:13:07] You end up accidentally creating and overwriting variables that you never intended to do.
>> Kyle Simpson: Since it's almost always an error, it turns out if we use strict mode, it is actually an error now. So all that same process that I went through in the previous slide, If I did it with strict mode on, which is what I am doing up here.
[00:13:33] I've turned strict mode on for the program or I could have done it at the function level. In either case, when we got to that line 11 now and we said hey, global scope, I have this LHS for bam, ever heard of it? The global scope would be prevented from creating that variable because of the strict mode and its only other option then would be to throw an error because it can't create one implicitly.
[00:13:57] It would have to throw an error and specifically the error it would throw is called a reference error. Reference error, bam is not defined. That's literally what it's saying. That does not mean the same thing as reference error bam is undefined. Remember, earlier in our course we talked about the difference between undefined and undeclared.
[00:14:25] Bam is an undeclared variable that we just start trying to assign to. It is not an undefined variable. An undefined variable would be one that was existent that did get declared, but at the moment had no value. That's undefined. I really wish that error message, that reference error bam was not declared.
[00:14:50] Because that's a much more accurate statement. I've been asking them to fix that error message for about five years, and they have yet to fix it.