 Hello and welcome to the NPTEL course on an introduction to programming through C++. The topic for today's lecture sequence is recursive functions and the reading for this is chapter 10 of the text. So to introduce the topic of recursion let me observe that many physical and abstract objects have the following interesting property. The object has parts which are similar to the object itself. So the natural question is what role is this similarity going to play in the computation and that is where recursion comes in. So such objects are said to be recursive or set to possess recursive structure. Now one such object could be computation itself and computation may also possess recursive structure and in fact you have seen an example of this already. While computing the GCD of mn we said that we really should compute the GCD of n and m mod n. So it might seem that a function that finds the GCD of m and n should call itself with arguments n and m mod n. It turns out that this idea works beautifully and such recursive functions are extremely useful. Recursive functions are also useful for processing recursive objects and in this lecture sequence we are going to see all of these things. So let me remind you of Euclid's theorem on GCD which we used earlier. So the theorem says if m mod n is equal to 0 then GCD of m and n should be n is n, else the GCD of m and n is the GCD of n and m mod n. If you look at this theorem it almost looks like a program, it looks like an if then else statement and nothing more. So you might think could we perhaps write it like that. So in GCD mn and inside that the computation that you perform is if m mod n equal to 0 then return n because in this case the theorem says the GCD is n otherwise we return the GCD of n and m mod n that is it. So this seems like a reflection of the theorem and really compact program. The question is will it work? It looks too good to be true perhaps. So let us see, let us use the rules that we have mentioned for how functions execute and let us see what will happen if we try to execute this function. And so I have the function on the left hand side and the main program on the right hand side and the main program is doing nothing much it is just invoking the function with arguments 205 and 123 and printing out the result. So when this program executes, so of course first the main program starts executing and for that the activation frame is created for main program. Now when the main program encounters the GCD statement, the GCD call then you know that the main program suspends and we create an activation frame for GCD. So this activation frame will get created. So GCD will now start executing with m equals 205 and n equals 123. So when it executes m mod n will not be equal to 0 so therefore it will go to the else part and it will return the GCD of n which is now 123 and m mod n which is 82. So that will create another activation frame. So another call, so another activation frame and then the first call is going to suspend. So after that the second call is going to start executing and this time m has the value 123 and n has the value 82. So again in the first step of execution m mod n will not be equal to 0 so the else statement will be executed. In this case we are going to return the GCD of n which now is 82 and m mod n which is 123 mod 82 which is 41. So we require that the GCD of 82 and 41 be returned. So this will naturally require this call to suspend and a new call and a new activation frame to be created. So this is it. So now we have an activation frame of GCD called with arguments 82 and 41. So note that at this point we have actually 4 activation frames in memory. So the main program had suspended and therefore its activation frame is present. The GCD, the first call has suspended so its activation frame is present. The second GCD call has suspended so its activation frame is also present and the last GCD call that we are currently executing is executing. So it also needs an activation frame. So this GCD call has arguments 82 and 41. So when we now try to execute this call so m has value 82, m has value 41. So this time m is a multiple of n, 82 is just twice of 41. So this expression will turn out to be 0 and therefore we will return n. So this call is going to return 41. So that 41 will be sent back. So the 41 will be sent back and we come back to the activation frame of GCD 123, 82. So remember this call had been waiting to receive a value so that it can return whatever value it receives back to its caller. So it has received the value 41 so it can return 41 back to its caller but of course before that the activation frame of 82, 41 will disappear. And now this call will return 123, 82 and that will activate the very first call we made. So this call will get activated because it has received the value and it will attempt to pass this value back but of course before this activation frame will go away and then we will this last, this very first call actually will pass the value it receives from the call that it made it will be passed back to main. So main will have finally received the value that it wanted over here and then this activation frame will go away and main will actually do this printing and so it will print 41. And as you can see 41 is indeed the greatest common divisor of 205 and 123. And so all this seems to have worked quite well and indeed it does, we will see in little bit more detail why it does and it is actually quite similar, the execution is actually turns out to be quite similar to the execution of the program, the non recursive program that you wrote earlier. So let us take a demo of this just to make, just to see that this actually runs and get a little bit more comfort with this. So this program is the same as the program that you saw except for a few minor changes. So first of all just to let us see what is going on, I have put out this print statement at the very beginning of GCD. So before GCD executes it will tell us what arguments it has received. So that is what this print statement is doing. Next at the end before GCD exits I would like to print out what value it is going to return. So therefore I have created a variable result into which the result to be returned is first put in. So if m mod n is equal to 0 then we put n into result, otherwise we make the call GCD and then the result of that is put into result. So this execution is really the same as the execution that we had on the slides except that we are going to print some messages and to print those messages we are having one extra variable. So after the result is put over here we print out what is returned and then we return the result. So basically from the main program we want, we are printing a little bit more descriptive message so that we can get to know what result was actually returned. So we print out this message and print out the result and even for this the GCD is not directly printed but we first put it inside a result, a result variable. So let us compile this and execute this. So I hit dot slash a dot out and this is what happens. So what has happened? The first call was indeed as we expected it was executing GCD with arguments 205.23. After that the second call was made 123.82, after that the 82.41 call was made. This is exactly what happened on the slide as we saw. Then the last call that was made returned and it returned the result 41. Then the call before that returned and that returned the result 41. And then the call before that returned and again the result that was returned was the same and this is the print statement that we put in in the main program. So the main program also receives the value and that value is indeed 41 and so everything is fine. So what have we seen here? Well we have seen recursion and let me just define it so to say. So recursion is simply the phenomena of a function calling itself. Now it might seem like we are defining the function in terms of itself and that is not a good idea. So I mean if we are defining a term then we should define the term using some other terms. But here that is not a problem actually. So there is no circularity in this definition because when we make the new call the arguments to it are different from the arguments in the original call. So there is no circularity over there and the new call is going to execute in its own activation frame. So we have also seen that and we have also seen and I guess I should point out over here that this process can go on indefinitely if we are not careful and that is what might happen if the arguments to the new call for example are the same as the arguments to an old call because then exactly the old execution will happen. So we do not want that to happen. So we want to make sure that some execution, some call must return without any recursive call and if you remember that did happen in our execution and if that does not happen then we have a problem because there is infinite recursion. Now in this example, in this GCD example in the body of GCD there was just one recursive call. We can have several recursive calls if we wish and in fact we will see an example very soon. Before we go to more examples I just want to observe, I just want to compare how the recursive and non-recursive versions of GCD work. So first this green portion is the recursive GCD and the red portion is the non-recursive GCD that you saw some time ago in the last lecture. So now let me first mention that if we look at the recursive calls in GCD, so we were calling this with GCD of 205, 123 then that recursive, that call made a recursive call GCD 123, 82, that made a recursive call 82, 41 and then that returned. Now let us see what are the computations that happen in the non-recursive function. So here we are going to look at what values M and N take in consecutive iterations of the call to GCD of 205, 123. So the first time around when we call GCD with 205, 123 M and N will take values 205 and 123. Now some iteration will, this iteration will take place and as a result of it M and N will change and you will see that in the next iteration the values are 123, 82 and in the iteration after that the values are 82 and 41 and after that the answer 41 will be returned. So if you notice the M and N which were the arguments over here really are taking the same values as the variables M and N over here. So in a sense the recursive and non-recursive GCDs are really doing the same computation. So in a sense we really do not need to worry about is this going to be correct. So long as we can establish this correspondence and we can establish that correspondence then we will know that the recursive GCD should also work. So that is certainly a reassuring fact over here. However, I should point out that for every recursive function there need not be a natural non-recursive function that does the same thing. So the question of how to think about recursion and how to argue that recursive functions are correct is still there but here for this GCD you can sort of see that it really execution of the recursive function really mirrors the execution of the non-recursive function. And but the point to note is that on the surface they look very different. The non-recursive function is a bit longer and somehow it seems to be doing a lot more stuff. So it should be observed that recursion often produces compact and rather elegant programs, elegant because the program is sort of following the main theorem that is the basis of that function. Now I should also point out that recursive programs might be slightly slower because they need to create the activation frame and destroy the activation frame which the iterative or the non-recursive programs do not have to do. The exciting point about recursion and we will see this in a later lecture is that recursion is also a way to discover algorithms and you may say that Euclid quite possibly did this, possibly he thought something like the following. Instead of doing laborious computation to find the GCD of 205 and 123, can I find two smaller numbers whose GCD is the same as that of 205 and 123 and this is exactly recursion. This is recursive thinking and it is quite common in mathematics and therefore it is certainly a powerful tool in designing algorithms and we are going to see more examples of recursion in this lecture sequence as well as in subsequently lecture sequences. So here is an exercise, it asks you to write a recursive program and you are supposed to consider our GCD program and sort of follow it but for this new function that is to be for which the program is to be written. So what did we discuss? So we said that recursion is a function calling itself during execution then we said that recursive function we found we saw a recursive function to find the GCD. Then we made a comparison between the recursive and non-recursive GCD functions and we saw that the recursive GCD is more compact and elegant even though both of them are doing the same computations. Next we are going to talk about recursive objects but let us take a break.