[MUSIC] We want to think a little bit about these names that we have been talking about. We've said the variables have names, we said the functions have names. Let's talk a little bit about where you can use those names and how you can use those names. This idea is called the idea of scopes. Scopes indicate a place where variable names can be used. At a high level scopes are exactly that. A scope is the area in your code where a variable name works. So let's look, for example, at this code here. We can see that we have taken the main function and our dayGreeting code, and instead of passing dayGreeting the number two, we've replaced it with two variables, A and B. We've assigned A the value five and B the value three, and we pass dayGreeting the result of the expression A minus B, which ends up being two again. And the output of this code is three things being printed twice. Good morning, good afternoon, good evening. Good morning, good afternoon, good evening. Those printoff statements, we've added a little bit more information showing which loop we're currently in, just to get us a little bit more clarity about what's happening. So scopes, one way to define a scope is by the curly braces. So we've seen curly braces a lot, and we know that they encapsulate code, but it also encapsulates a scope, or a place where names work. And so in that main function you can see that there are scopes for, there's a curly brace at the beginning of the main function and at the end of the main function. And within that we have one scope. DayGreeting also has a set of curly braces that define its body and within that there's a scope. And the for loop also has curly braces and within that there is a scope. So, what does that mean? Well, scopes have some properties. For example, scopes are bounded. So, if we replace the I that was in day greeting with A, under, past good afternoon, after good evening, replace that I with B. Referencing the variables As and Bs, you can see that we get an error from the compiler in this case. That's because the variables A and B aren't known within the scope of dayGreeting. A and B are known within the scope of main, and that scope is defined by those curly braces. So if we try and use A and B outside that main scope the compiler doesn't know what to do, that's the syntax of C. It can only be used within the scope in which the variables are defined. Scopes are also ordered, so within this scope, what we've done is we've moved the definition, within the main function, we've moved the definition, the declaration of B, to below the call for dayGreeting. And in this case, what we see is that the compiler gives us an error for using the name B before we have defined or declared it. And so in this case we've seen that although B is within the correct scope of the main function, because scopes are also ordered from top to bottom and because B is defined and declared after it's used the first time, the compiler gave us an error. Scopes are bounded, scopes are ordered. Scopes also do something called defining a namespace. What that means is that within a given scope, you can use a variable name that has been used in another scope before. So we've done that here in this example. We've shown a variable A equals five in main, and variable B equals three in main, and we've used them in the call to dayGreeting. But within dayGreeting, we've defined a new variable called A, and a new variable called B, and we've used them in those two print F statements. And you can see that when we run this code, and we print out good afternoon and good evening, we get the values of the variables A and B that are within the same scope as those print F statements within dayGreeting. Namespaces are an area in which names are, you have to be unique. So main has a scope and a namespace, and dayGreeting has a scope and a namespace, and within each namespace you can use a name again. Finally, scopes can be nested. And we see this here in the example of day greeting in which we have curly braces within curly braces. So the curly braces in the foreloop are within the two curly braces of the day greeting group and we can see that int A has been defined outside the scope of the foreloop, and int B has been declared within the scope of the foreloop. And when we run this, we have no problems executing that because A is also defined in any nested scopes, as well. Here we see an example where the nesting gets broken. We have defined A within the scope of dayGreeting, and we have defined B within the scope of the foreloop. But after we close the scope of the foreloop, we try and use B again. The nesting property says that you can use any variable that's been declared in a higher-level scope than the one you're currently in, but you can't use a lower-level scope. It's kinda like a tree structure in that way. So in this case the compiler errors when we try and use B because B was defined within the foreloop, not within dayGreeting. There's also a B within main but that's a different B because that is a different namespace as well. So in this case B does not have a definition at the point at which it's used. You can kind of look at this in kind of a ridiculous example here, where we just set up some code to demonstrate namespaces and scopes. We declare an A, B, C, D, E variables, and we have a bunch of nested scopes. And you can see that the error that X code gives us in each case reflects the first variable that's being used that's not within the current name spacer within the current scope. So the most nested print off line, we can use A, B, C, and D, and there's no problem there. The next most nested print off statement, we can use A, B, C, and D and E as well, because E is defined in the same scope. But as we move out, each curly braces we move out, we lose the definition of one variable. If you declare a variable before a set of curly braces, for example, when we do int D equals four and then we have an open curly brace, that variable is still declared once you close that nested curly brace, as long as there's an equal number of openings and closings. Now, there is one special scope and that's called the global scope. Names in the global scope can be accessed from anywhere. This is very convenient, but it's also very dangerous. Let me explain why. Here's an example of trying to use the variables A and B within dayGreeting and when they haven't been defined within a scope. What we could do is rather than defining A and B from within main, we could move them outside of any scope within our file, declare them before dayGreeting, and now any place within our file that we use A and B, we're referring to that global version of A and B that's accessible without having to worry about scoping. This is going to execute without any trouble, but this introduces some subtle errors, some nuances that you have to be careful of, and it's generally considered bad programming practice to use too many global variables. Here's something that can happen. If you use global variables then you can mess up unintentionally by overriding a global variable you intended to use or by using a variable that you didn't want. And here's two examples of that. So you could override a global variable in this way. So say, for example, you're interested in using the values of A and B from main, and we have declared A and B in the global scope. Well, when we run main A and B are overriding, when we run main the version of A and B that are declared within the scope of main are overriding the global variables that were declared about dayGreeting. They're within a more nested scope and they block access to the global version. So dayGreeting gets called with the results of seven minus six but within dayGreeting that int and int B from main aren't declared and so dayGreeting, when it refers to A and B, are referring to the global version of A and B. And this is sort of a strange confusion of the use of A and B within this file, and that's probably not what the programmer intended to do. The other thing that can happen is you can use a variable you don't want. So for example, let's say you've declared A and B in the global scope, and in dayGreeting, you intended to declare A and B as well. But you forgot, and you only declared A. Well, the compiler is not gonna give you an error because B has been declared, just not in the scope you thought. It's been declared globally. So when you do good afternoon A, you're using the version of A that was declared within dayGreeting scope. But when you say good evening B, you're using the B that was declared in the global scope, and this looks kind of like an error. To help give you a clue to make sure that you're doing what you intended to do, Xcode will color-code your global variables in a particular way. In this case, kind of a teal color. That's a clue to you as a programmer that you may not be using the variable that you want, especially if you have a parallel structure here, like good afternoon A, good evening B, and you see that the color is different between the two. Functions also exist in a scope. That's interesting. Well, it's not surprising, though, because functions have names and those names are in a namespace, and because functions are in a scope their names are unique within that name space. So up till now, all we've seen is functions being declared in the global scope. So those function names are accessible anywhere you call them, but later on, we're gonna introduce an idea called classes, which is going to provide a scoping for function names, and the way that we saw the curly braces provided scoping for variable names. As a side note, you may have noticed in some of the application development that we were doing, a lot of the variables started with a capital N and a capital S. What's with that? Why do all the variables start with those letters? Well, NS is an acronym that stands for NeXTSTEP. NeXT was a company whose legacy Apple inherited and whose code Apple continues to use. Certainly the variable names. When it was being developed, NeXT engineers wanted to make sure that their global variables and global functions didn't conflict with yours. They didn't want you accidentally using a variable that had a common name or a function that had a common name, and using their code when you didn't mean to or using your code when you meant to use the global code. So what they did is they put NS in front of their names, primarily of their types and some of their functions, so that you wouldn't confuse your code names with theirs. They basically claimed ownership of any name that starts with NS and that helps to reduce confusion within the code base. You can have a lot of global variables floating around. Another question is how far does global extend? Well, when you're typing into Xcode as an editor, when you're editing your code, Xcode is only going to give you information about global variables that are in the current file. You're gonna get color codings and you're gonna get warnings associated with global variables that are within the file that you're editing. But, when you go to compile your code, Xcode may give you errors that reflect the fact that you're using the name of a global variable that either hasn't been defined, or that has been defined twice within your code. And that could be because you've defined a global variable and you're using someone elses code, or you yourself have defined the name of that variable somewhere else as well, but in a different file. So within a file the editor will give you live editing information about problems with global variables. But sometimes when you compile, you’ll get told that there are other variables that have the same name, and that’s gonna cause your compile to fail. So an Xcode builds your program, if you use the same global name anywhere in your project, the linker is gonna give you an error. So, in summary, scopes define a namespace. Variables have names, and functions have names, but those names are only applicable within that namespace. Within a given scope, order matters. So as you declare things from top to bottom, the names at the top can be referenced after they've been declared, but not before. A special scope is the global scope. Anything that's defined in the global scope can be found by anything else. This can cause problems though, so you have to be careful about unintentionally using variables in the wrong scope. And a good practice is not to use global variables if you can avoid it. Thanks. [MUSIC]