 there we go oops so if we hit or sorry if we do 2 to the 4 well we would call exponent 2 4 that would go into our recursive case so it would go into that else statement and it would do return well 2 times exponent 2 to the power of 3 so before that function returns that called 2 to the 4 it has to actually compute 2 to the 3 so we would do another function call so this is another function call so I put it here on the stack to indicate that the other one is still active it's waiting for this one to complete so right here in the gray text that is what we're trying to compute and every box is a new function call that would have its own local variables in this case it would be b is 2 and n is 3 so to evaluate exponent 2 to the 3 that would go into the recursive case so we would get 2 times exponent 2 to the 2 okay well now we have to figure out what exponent 2 the 2 is that is another function call so we call exponent 2 to the 2 then that gets into the recursive case again so we get 2 times exponent 2 to the 1 then it gets kind of boring so then we do have another function call with exponent or 2 to the 1 and then well that is 2 times exponent 2 to the 1 so we would call that and then mercifully this is our base case so in this case n is equal to 0 so it would just get a 1 so it would return 1 so the function that called it gets a copy of 1 and this whole thing kind of unravels itself so then it would return and then in our 2 to the 1 function we would calculate 2 times 1 which is just 2 and then that is the result for 2 to the power of 1 so that would get returned for this function call then we have 2 times 2 so that would be 4 so that's 2 to the power of 2 and then it would get returned here and then all kind of unravels right so now here that 4 is returned it gets a copy of it so then we would do 2 times 4 which is equal to 8 which is thankfully to the power of 3 and then here well we would return 8 so then we would get 2 times 8 and then we'd get finally our final answer 16 so lots of steps it would be in that case what 5 function calls but we got the answer in this case a for loop would have probably been less confusing but is there any questions about how this work because it's going to get weird once we get Fibonacci going so we're all okay until it gets slightly more strange okay so let's go ahead and run it make sure it works so here's that exponent code so here I just have my base case and my recursive step oops and then if I go ahead and run it I could do to the power 4 something that I get 16 seems to work to the power 5 32 but if we implemented this with a loop I could probably do like 1 to the power of I don't know some large number and that would be fine it would just might take some time to execute right well let's see what happens here so if I run that I get a segmentation fault crap well I didn't even use malloc how in the blue hell do I have a segmentation fault so one of your steps might be okay well I'll use valgrind and then I'll see says okay I have no memory leaks I didn't allocate anything so what happened so you try and scroll up and then you get a bunch of random text that's probably not so readable the only thing that you have any hope of reading is this thing called a stack overflow so we know that kind of what a stack is it's where all the local variables are and in this case the stack overflow means basically it ran out of memory so this is a very common thing you can encounter once you do recursive functions because if there's too much recursion we essentially just run out of memory so I did what to the power of like a million or something like that so that would mean that you know a million called 999999 called 99998 called that called that called that called that and well every function that is active has a B and an N at least so it has two integers so I essentially just ran out of memory because every function call needs its own variables so that is what a stack overflow means basically just I ran out of memory so again like I said every time we call a function that function gets its own copy of the variables in C they store local variables on the stack so if there's many active functions at once so there I did one to the power of a lot so if I was to draw that on the slide I would run out of room because it would just call itself over and over and over again until it actually ran out of memory so running out of memory for local variables called stack overflow that is the name of the helpful website that you can get questions and answer to for programming questions so they named it that because well this is a common enough error that is really hard to go it means you have screwed something up because usually people get to recursion and then things start screwing up and then most programmers see stack overflow a lot when they are starting out so common cause for a stack overflow more likely than not is infinite recursion so it's similar to an infinite loop except in an infinite loop just takes a lot of time it doesn't actually need more memory each time you go through the loop for recursive functions it needs more memory essentially every iteration of the loop if we were thinking about loops so we can actually likely run out of memory before we run out of time so this is far beyond the scope of the course so don't worry about if this part doesn't make any sense but there are like certain forms of recursion that are more that can be optimized more easily so we can rewrite some functions to use what's called tail recursion so it's a special recursive function that just has a single recursive call in the return statement you do not need to practice actually rewriting this this is mostly for performance so if we modify exponent well we could create an exponent that takes three variables so before we just returned a number well like in a recursive case we did like two times the recursive function so if we want to be tail recursive we can't do that so we create another variable here that's local to the function called accumulator that just keeps track of the current value so in our base case instead of returning one we just return whatever the final value we have is so it would do like two to the two times two times two times two if we did to the power four then eventually it would be 16 and then we just return 16 at the end and this is our recursive case so we just do the calculation with the accumulator so we just multiply B by it and otherwise it looks the same as before so if we want to keep exponent looking the same well we have the base and the end and we can just return exponent written in this tail recursive manner by giving the accumulator one and then giving B at the end and the only reason why I show this to you is because compilers can optimize this function so if it's recursive a lot of people don't like writing recursive functions because well it wastes a lot of memory and you can get into the stack overflow issue where if you just wrote a while loop or for loop or something like that that would work better and you wouldn't have that memory issue so it's actually guaranteed that compilers and you'll learn this in like fourth year whenever you get to compilers but it's guaranteed that compilers will optimize this away so it will optimize away the recursive fall call and just convert that whole function into essentially a while loop so it would convert it to this for you so just start off in x equals accumulator so in our case we set it equal to one and then it would just go while n is not equal to zero and just do the recursive step over and over again so now our code doesn't have a stack overflow doesn't have that issue because we're not actually doing recursive function calls we let the compiler optimize it away for us and in this version maybe you can argue that the recursive one was more readable so you'd rather have it than this but for calculating an exponent probably just a while loop is going to be much much much easier to do but it's good to think of things recursively because well some solutions lend itself better to recursion than others so let's rewind a bit and see what happens when we call fib of four so this one is a bit different than the exponent where in our recursive step we return fib n minus two plus fib or fib n minus one plus fib n minus two so we do two function calls here so if we actually want to evaluate something like fib of four turns out it's going to be a lot of work to understand how your computer actually executes this code so gets a bit ugly so if we evaluate fib of four well we call fib of four and again I'll just write in the gray here what the function is supposed to be computing so it's supposed to be computing the fourth Fibonacci number so in order to compute fib of four well that's a recursive step right it should return fib three plus fib two so we have to do these function calls so C will go ahead and it does function calls in left to right order don't have to know that for the course but in order to figure out how this actually works on your computer it's important to know what happens first so we will do this function call for fib of three so we'll do that function call it'll get its own copy of n and we do fib of three well that goes into the recursive step so it would return fib of two plus one right then okay now we need to call fib of two okay so we call fib of two fib of two is equal to fib of one plus fib of zero mercifully when we call fib of one that is thankfully our base case right so it would immediately return one so that whole thing would evaluate to one and then it would return and give us the value one back for in this case fib of one so it returns and now oh no well we still have to find out what fib of zero is right so now we have to figure out what fib of zero is so that is another function call to figure out what fib of zero is that mercifully is another base case so that just gets the value zero so it returns and then we can finally figure out what the second Fibonacci number is so it's one plus zero so it would figure out that that is one okay great so that was figuring out what fib of two was so that would return the value one okay well now we have to do the other half of it now we have to do fib of one okay well that's another function call so we call fib of one mercifully that is another base case so that just returns one and then well that returns one so then we can figure out what the third Fibonacci number is so it's just one plus one so that's two so now that returns right so that is fib of three so that returns oh god but now we have to figure out what the second Fibonacci number is so that is another function call so this whole thing kind of goes again so we have fib of two okay well that's a function call oh that's our recursive case so we would return fib of one plus fib of zero whoa okay so then fib of one that's another function call mercifully that's our base case so that's just a one so then that would return okay yay so now we have to figure out what fib of zero is again so fib of zero okay that's another function call that goes to the base case mercifully we know it's a zero then it would return and now fib of two is done so we get one then that returns now we can finally figure out the fourth Fibonacci number which is two plus one which is three yay wasn't that fun so any questions about how that works other than it seems like it takes a long time to figure it out so let's see so here is that implementation and just as a review for the last one instead of just asking and doing scan F I'm just using that other version of main that takes another argument that I can type to it just because I don't feel like hitting enter two times so I checked that there's two arguments and then use AOTI to convert the first one to an int and I assume I'm being nice to it I'm just going to print the result of calling Fibonacci on whatever that number is so if I call fib of four it was a lot of work for us to figure out all the function calls and you know how they work and who calls what and what values and when do they stop but computers are fast so it just gets three quite readily and works so if we did computed 10 we get 55 turns out grows pretty fast 20 we get 6000 something like that seems to be pretty fast computers are quick but if we get 40 you might have noticed that took a little bit of time maybe 44 44 took a bit of time it was a bit slow and also for this one we could just write it in a for loop to and it would be way faster and way easier to actually compute but again we're just kind of practicing practicing recursion even though doesn't really make sense this would be a lot easier to just do in a for loop so any questions so far about evaluating that yeah so the question is do we know how much slower it will be depending on how many steps it will get so you can kind of guess it's going to get like in this case almost two times slower every time because well if I have to compute 44 that means it has to compute 43 and then 42 and then if I have to compute the next one well I have to compute 44 which is going to take as much as what I ran before plus of 43 so not quite two times slower every step but gets up there so if I do like 45 probably pretty slow yeah oh crap so oops so if I do 44 one Mississippi to Mississippi takes a bit of time if I do 45 one Mississippi to Mississippi three Mississippi for Mississippi okay so took about twice as long because essentially has to calculate everything it had to do before and then do it all again for the next number and then you might imagine this might be like exponential so I have to compute one side and then the other side and then I have to do it again and again and again and it's kind of a pain so that leads us to our next thing which is we can significant whoops wrong thing leads us to the next point of again so this part again is beyond the scope of the course for this course just writing recursive functions is good enough for us we'll get some more practice as it goes on but just so you know you can significantly speed this up without actually changing it from being recursive with something called memoization which is just a fancy word for caching and cat caching is just a fancy word for just saving values that you don't so you don't have to recompute them so even with fib of calculating fib of four well we had to calculate like fib of two a lot of times and we had to calculate fib of three once and fib of two a bunch of times and then a lot of well we didn't have to calculate the value for fib of one or fib of zero but we could change our program a little bit so we don't have to go ahead and recompute them over and over again so what optimization we could do that you could probably implement right now but you don't have to for this course it's just I could just remember some older value in an array and then if I've already calculated that value before I can reuse it again instead of recomputing it so this one took I almost counted like five Mississippi it was really really really really really really slow so I wrote another version of it that just that just saves the value that is computed already so it just reuses it over and over again instead of doing the whole recursive nonsense over and over again and if I run that whoops that is the same function so if I run my optimized version boom look how fast that was so there are some techniques you might employ that some problems will have to be recursive and they might be slow and this is one technique to speed it up again just something to think about don't have to do that in the context of this course at all but it will come up you know probably in your next programming course so recursive functions are basically just another tool some problems are easier to think about recursively especially if you're like more of a mathy person that likes proofs and all that stuff was never me so it took me a bit to figure out this recursive thing but some problems believe it or not are actually easier to solve recursively so it's good to get some practice trying to get yourself into that mindset so typically recursive functions they're going to take more space to execute tail recursive functions can be optimized again don't have to know that for this course but in your career that might be a good thing to know and try to write for so it's important to practice so you can go ahead identify these types of problems and be able to solve them and the main two things are given a problem you probably want to identify a base case so something you know a value for given one of the inputs and then you also want to create the recursive step so you want to solve the problem in terms of itself sorry you want to solve the problem in terms of a smaller version of itself so typically it'll be you do one thing like you just take one step and solve that so let's think about that for more practice can we write a recursive function to calculate factorials so sit think about it for a few minutes and then we will try and come up with the code ourselves together so we're trying to calculate factorials and like for an example well the like four factorial would be four times three times two times one so take a minute think about how you would solve that and write that as a recursive function so these are the types of things that would be on exams and stuff like that like for this course most of the problems you'll see you can probably solve with like a while loop or something like that because well you have to be able to write them during an exam and recursive stuff takes practice so generally you'll probably get some question the file will be like solve this problem with a recursive function all right I'll give you a few minutes for that and then we'll try and think about what these steps would be I can't hear you sorry okay so I'll take you first so you you you will start half of it so the first thing we need is a base case that's been answered up there so our base case would probably be well if we're computing like n less than two so if we're computing the factorial we'll assume no negative numbers if we're computing one factorial or zero factorial well they're defined as just being the value one so that is our base case so I'll get someone else for the recursive step so that is one thing we need so the other thing we need is our recursive step so anyone with the idea of what we should do in the recursive step so how do we solve factorial in terms of itself yeah yeah so my recursive step I could write in it else here a return doesn't really matter so in terms of solving in terms of itself well let's assume the number is four so in order to calculate four factorial well that's just the same as doing four times three factorial so if we wrote that in terms of c function calls our recursive step would be to return n times n minus one factorial which would just be factorial n minus one everyone agree with that so turns out this one might be easier to think about than doing all the four loop and everything like that so if we do I don't know four factorial 24 10 factorial some large number seems to work cool that was faster than I expected any questions about that yeah so the questions can I do a recursive macro I'm not sure if the c-pro pre-processor lets you define recursive macros I'm actually not sure I don't think so it's fairly straight forward and simple and I would probably complicate it so I don't think you can but can do recursive functions no problemo so any questions at all about factorial all right wow I did myself so here's the solution for you so same thing we developed so important things so we will get a much much much much more complicated example in the next lecture I even have fun toy props that I can bring in but for this one just to remember a recursive function just a function that calls itself in order to think about the problem while your solution needs two things so you need a base case so which is basically a simple solution you know so something you know how to do that you don't have to think very hard about and then the other one is your recursive step that you'll have to develop which just solves the problem in terms of a smaller version of itself so the idea here is since it's a smaller version of itself you're making progress each step you take eventually you will hit the base case and then you can just let your computer solve it for you so yeah we're really 13 minutes ahead all right cool I like it all right so all we'll just stick around for the remaining 13 minutes but just remember pulling for you we're all in this together