 A thing which is global in code is the opposite of local, a thing which is global exists everywhere throughout the program and so can be used anywhere. In Pigeon, functions are always global, and any variables you create outside of a function are also global. Here we have three global things, a function elison, a function json, and a variable cat. The function elison uses the global variable cat, such that when it is called, it prints the value of cat, which at this time is the string rubber. The function json also uses the global variable cat, but it assigns to it. Now normally an assignment in a function creates a local variable of that name, but because here we have a global variable named cat, any assignment to that name is going to assign to the global, not to any local. So effectively, if we have a global variable named cat, then we can't have any local variables named cat in the same program. Again, this is a crude solution to the problem of name collisions, as we'll see later most languages have rules that accommodate the existence of globals and locals of the same name. Anyway, when we call json with a string glue as argument, that string gets assigned to the parameter x, and so gets assigned to the global variable cat. So when we subsequently invoke allison again, it prints the current value of cat, which is now the string glue. In Pigeon and in many languages, functions are actually a type of value. This means we can assign them to variables and can pass them as arguments. So say I have the function here, gena. I can assign gena to a variable dog, and then I invoke dog as a function. It's the same as invoking gena, because at the time of this call, the variable dog references the function gena. Or say I might have another function, harry, with one parameter total, which it invokes as a function. So if I call harry with the argument gena, gena gets passed a total, and so when total is invoked, gena gets invoked, printing high. It's also possible to return a function from another function. Here we have a function alec with one parameter cow, and depending upon whether cow is true or not, the function returns either the function harry, or the function gena. Something which is recursive is defined in terms of itself. This may sound like a logical impossibility, but in fact it's not. We can have recursive functions. A recursive function is a function which somewhere in its body invokes itself. Here's a function Jessica, which prints high and then invokes itself. What's going to happen when we invoke Jessica is that it prints high and then invokes itself, and this second invocation also prints high and then invokes Jessica, meaning a third invocation will also print high and then invoke Jessica again. And this will happen ad infinitum. Jessica is an example of direct recursion, but it's also possible to have indirect recursion. Here we have a function kelly, which prints a, and then invokes mic, and a function mic, which prints b, and then invokes kelly. So what happens when we invoke kelly is that it prints a and invokes mic, and the invocation of mic prints b and then invokes kelly, thus perpetuating an endless cycle. We'll see a and b printed in an endless loop as kelly calls mic and mic calls kelly. Both kelly and mic here are indirectly recursive because an invocation of kelly will indirectly result in more invocations of kelly, and an invocation of mic will indirectly result in more invocations of mic. Now in both of these examples of recursion, the recursion is infinite, resulting in unending loops. This infinite recursion you might imagine is not generally desirable. We don't want our programs to get stuck doing the same thing forever. Usually when writing recursive functions we want them to stop invoking themselves at some point. The classic introductory example of such a function is a recursive version of a factorial function. We of course already made a factorial function using a while loop instead of recursion, and this actually demonstrates a good point. When you can do iteratively with loops, you can do recursively. So the question is, when is one approach more appropriate than the other? Most programmers find iteration easier to reason about than recursion. On the other hand, recursion offers more elegant solutions to certain classes of problems. Computing a factorial, however, is not in one of those classes. The iterative solutions and the recursive solutions are about equal in simplicity as both approaches take only a few lines of code for this problem, so simplicity and elegance are not really an issue here. On the other hand, depending upon how the language you're using is implemented, in particular how it uses function calls, in some cases a recursive solution may use a lot more memory than an iterative solution for a reason we'll discuss in a moment. So here's a recursive version of a factorial function. Note that this way of competing a factorial is actually an elegant expression of how the factorial operation is defined. First we have the special case for the factorial of 0 which always returns 1, but then the factorial of any positive integer is the same as multiplying that number times the factorial of 1 less than that number. Looking at an example, this checks out. For instance, the factorial of 5 is 5 times 4 times 3 times 2 times 1, and the factorial of 6 is 6 times 5 times 4 times 3 times 1. So the factorial of 6 can be expressed as 6 times the factorial of 5. Now walking through the code, first what happens with an argument of 0? Well, when n starts at 0 then the test of the if condition will be true and so we're going to return 1, the correct answer for the factorial of 0. But what about an argument of 1? Well, first the condition n equals 0 will test false, so we'll skip to the second return statement. And in this return statement, just keep in mind that expressions are evaluated inside out. The operations in the inner parentheses get evaluated first. So first evaluated is the subtraction, then the call to the factorial function, then the multiplication, and then what that multiplication operation returns is what this return statement returns. So first the sub-operation returns n, subtracted by 1, 1 subtracted by 1 is 0, so factorial is invoked with the argument 0. As we just established, the factorial function invoked with the argument 0 returns 1, so the multiplication operation has the operands n and 1, and still has the value 1, so this is 1 times 1, which is of course 1, so the second return statement ultimately returns the value 1. Now what if we call the function with the argument 2? Well the if condition again returns false, so we skip to the second return statement, but now n has the value 2, so n minus 1 returns 1, and factorial is invoked with the argument 1. As we just established, the factorial function invoked with the argument 1 returns 1, so the multiplication operation has the operands n and 1, and has the value 2 this time, so this is 2 times 1, which is of course 2. So the second return statement ultimately returns the value 2. You should see a pattern here. When calling this factorial function with an argument of n, the function will recursively call factorial with the argument which is 1 less than n. So when we call factorial with an argument of 15, for example, the function will recursively call factorial with the argument 14. And in that call to factorial, the function will recursively call factorial with the argument 13, and so forth. What we get effectively is a chain of recursive calls. A call to factorial with an argument of say 5 will trigger a chain of recursive calls with the arguments 4, then 3, then 2, then 1, and then finally 0. What's special about the argument 0 here is that that call to our factorial function will not trigger another recursive call. The call with argument 0 will simply return 1. The argument 0 here serves as what is called the base case, the case in which a recursive function will stop making more recursive calls. Once the call with argument 0 returns, then the call with argument 1 can return, then the call with argument 2 can return, and so forth back up the chain. So note that the last recursive call is actually the first to return, while the original call is the last to return. This actually is how a chain of function calls will always work. The last function called in the chain is always first to return, while the first call in the chain returns last. The key thing to understand about recursive chain of function calls is that as we discussed when talking about scope, each call to a function has its own set of the local variables. In this case, our function has just one local variable n, but each recursive call has its own n. When the call to factorial with an argument of 15 invokes factorial with an argument 14, those two invocations have their own n, the first with the value 15, the second with the value 14. This actually explains why I said earlier that recursive solutions can often be less efficient than iterative solutions. In our iterative factorial function, we only had two local variables no matter what argument we called the function with. In our recursive function, though, we have a variable taking up memory for each recursive call. So say, invoking the recursive factorial function with the argument 1000 would require enough memory to store 1000 variables. When memory usage is a concern, this extra cost to recursion may be something to watch out for.