Recursion: The Call Stack
Recursion: The Call Stack
Say you want to plant 100 seeds, but you can only afford a single seed. Only being able to afford one seed feels pretty insignificant, we know, seeing as they cost, what? Ten cents? We're not here to judge your budgeting skills, though. We're here to do computer science, so let's continue with the hypothetical, shall we?
You buy the seed and grow a plant, which produces three seeds. That's closer to your goal (three seeds closer, by some estimates), but you're still pretty far from 100 seeds. You keep going: you plant each of the three seeds to grow three more plants and each one has three of its own seeds. Now you've got nine seeds from the harvest. If you plant these again, you'll get 27 seeds, then 81, and finally 243, which is way more than your original goal. #Overachiever
In recursion, the goal—the end condition—is always the base case. It's the bottom of the barrel, the end of the recursive calls. If a recursive method calls itself, it has to stop when it hits the base case and work its way back up to the original method. Each recursive function calls itself until hitting the base. Then, when the case becomes true, the result floats back to the top of the call stack, a list in the computer that keeps track of all the functions called in a program. The fact that programming languages have call stacks is hugely important to recursive functions.
Don't worry, we'll explain momentarily…like after-this-piece-of-code kind of momentarily.
FUNCTION GrowPlant (SeedCount) { IF SeedCount >= 100 PRINT "We've reached the base case with a seed count of: "+ SeedCount RETURN SeedCount END IF PRINT "The current count of seeds is: "+SeedCount RETURN GrowPlant (SeedCount * 3) END FUNCTION
If you call this function with one seed, it'll print out:
The current count of seeds is: 1 The current count of seeds is: 3 The current count of seeds is: 9 The current count of seeds is: 27 The current count of seeds is: 81 We've reached the base case with a seed count of: 243 The final seed count is: 243
The call stack is at the heart of this recursive function—and all functions, TBH. The call stack keeps track of function calls. It's a list of all the functions currently running at that that point in the program. Some programmers call it the program's planner for that reason (probably). Any time the call stack hits a RETURN
, it pops the current function off the stack and goes back to whichever function's now on top.
You can pretty much trust that the call stack's always going to be more organized than you. It happens.
Say the base case for the seed example was nine instead of 100. That means we'd only call the method three times before heading back up the call stack. If we had some sort of magical power to print out the call stack while the code was running, it might look something like the chart below.
Step 1 | Step 2 | Step 3 | Step 4 | Step 5 |
GrowPlant(1) | GrowPlant(1) | GrowPlant(1) | GrowPlant(1) | GrowPlant(1) |
GrowPlant(3) | GrowPlant(3) | GrowPlant(3) | ||
GrowPlant(9) |
Each time the code calls a function, that function gets added to the stack. Once a function ends, it gets taken off the list and the code returns to the calling function. So…when growPlant(3)
calls growPlant(9)
, it's going to wait until growPlant(9)
ends before it can also end. Once growPlant(9)
ends, growPlant(3)
finishes its run. It's like that, but for all the functions.
It also makes an upside-down pyramid when put together (apparently).