Callstack and why it's important to understand in development

in #programming โ€ข 5 years ago (edited)

๐˜๐˜ง ๐˜ข ๐˜ฑ๐˜ณ๐˜ฐ๐˜จ๐˜ณ๐˜ข๐˜ฎ๐˜ฎ๐˜ฆ๐˜ณ ๐˜ฅ๐˜ฆ๐˜ด๐˜ช๐˜จ๐˜ฏ๐˜ด ๐˜ข ๐˜ฑ๐˜ณ๐˜ฐ๐˜จ๐˜ณ๐˜ข๐˜ฎ, ๐˜ฐ๐˜ฏ๐˜ญ๐˜บ ๐˜ฉ๐˜ข๐˜ญ๐˜ง ๐˜ต๐˜ฉ๐˜ฆ ๐˜ซ๐˜ฐ๐˜ฃ ๐˜ช๐˜ด ๐˜ฅ๐˜ฐ๐˜ฏ๐˜ฆ ๐˜ช๐˜ง ๐˜ต๐˜ฉ๐˜ฆ๐˜บ ๐˜ฉ๐˜ข๐˜ท๐˜ฆ ๐˜ฐ๐˜ฏ๐˜ญ๐˜บ ๐˜ฅ๐˜ฆ๐˜ด๐˜ช๐˜จ๐˜ฏ๐˜ฆ๐˜ฅ ๐˜ต๐˜ฉ๐˜ฆ ๐˜ฅ๐˜ข๐˜ต๐˜ข ๐˜ด๐˜ต๐˜ณ๐˜ถ๐˜ค๐˜ต๐˜ถ๐˜ณ๐˜ฆ๐˜ด. -- ๐˜›๐˜ฉ๐˜ฆ๐˜ฏ๐˜จ, ๐˜‘๐˜ฐ๐˜ฏ๐˜ฆ๐˜ด, & ๐˜›๐˜ฉ๐˜ช๐˜ฎ๐˜ฃ๐˜ญ๐˜ฆ๐˜ฃ๐˜บ

For this article I would like to shed light on a complex side in programming, and that is understanding the callstack.
I'll go over the JavaScript callstack as it's one of the most popular languages in todays programming ecosystem.

The callstack may seem a bit daunting (maybe like the godzilla gif below) "Everybody runnnn for your lives!!" But if you make it through this article, my hope is that it will provide you with better insight on the topic and give you a general idea of how the callstack operates.

I don't believe it's discussion is popularized in modern web development because it has many layers and is quite deep in theory. The word we usually use for that is "abstraction" - where you take something complicated and put a nice interface around it so that you don't have to deal with the complexities.

The callstack is a very low level concept, It goes deep in showing you all the layers of your program - including the framework code. That's why I believe understanding it will be of great use as you can pick apart where your code is going and what's happening to it.

I'll go over various topics such as:

  1. How functions enter and exit the callstack and what happens if they never exit the callstack

  2. How and why I believe the callstack is like a washing machine.

  3. Why the callstack is an absolute necessity in coding

  4. How the code we provide to our callstack (washing machine) can cause the callstack to not work as we expect

For our first example we'll start with an extremely basic recursive function:

(๐˜ง๐˜ถ๐˜ฏ๐˜ค๐˜ต๐˜ช๐˜ฐ๐˜ฏ ๐˜ญ๐˜ข๐˜ถ๐˜ฏ๐˜ฅ๐˜ณ๐˜บ() {
๐˜ญ๐˜ข๐˜ถ๐˜ฏ๐˜ฅ๐˜ณ๐˜บ()
})();

  • ๐˜ฉ๐˜ฆ๐˜ณ๐˜ฆ ๐˜ธ๐˜ฆ ๐˜ข๐˜ณ๐˜ฆ ๐˜ค๐˜ข๐˜ญ๐˜ญ๐˜ช๐˜ฏ๐˜จ ๐˜ต๐˜ฉ๐˜ฆ ๐˜ญ๐˜ข๐˜ถ๐˜ฏ๐˜ฅ๐˜ณ๐˜บ ๐˜ง๐˜ถ๐˜ฏ๐˜ค๐˜ต๐˜ช๐˜ฐ๐˜ฏ ๐˜ช๐˜ฏ๐˜ด๐˜ช๐˜ฅ๐˜ฆ ๐˜ช๐˜ต๐˜ด๐˜ฆ๐˜ญ๐˜ง ๐˜ธ๐˜ช๐˜ต๐˜ฉ๐˜ฐ๐˜ถ๐˜ต ๐˜ข ๐˜ด๐˜ต๐˜ฐ๐˜ฑ๐˜ฑ๐˜ช๐˜ฏ๐˜จ ๐˜ค๐˜ฐ๐˜ฏ๐˜ฅ๐˜ช๐˜ต๐˜ช๐˜ฐ๐˜ฏ ๐˜ฐ๐˜ณ "๐˜ฃ๐˜ข๐˜ด๐˜ฆ ๐˜ค๐˜ข๐˜ด๐˜ฆ"

As soon as you invoke this function it is sent to the callstack and creates what is known as a "stack frame" and will be temporaily stored until it has been returned.

If you visualize the callstack as a washing machine, we are bringing our laundry() function to the washing machine which is where it will be held until "washed" however, what would happen if we never took our laundry() out of the washing machine?

Great question! Notice anything odd about our function above? think about it for a minute. When you think you have it, scroll past Zach to review the answer

wฬถeฬถ ฬถnฬถeฬถvฬถeฬถrฬถ ฬถsฬถeฬถtฬถ ฬถaฬถ ฬถsฬถtฬถoฬถpฬถpฬถiฬถnฬถgฬถ ฬถcฬถoฬถnฬถdฬถiฬถtฬถiฬถoฬถnฬถ!

That's right! This is what's known as stack overflow and a common problem we'll all eventually run into in programming, we never took our clothes out of the washing machine, and you may aswell throw a brick into it:

You'll also end up with a nasty error like the one below:

Screenshot from 2019-12-06 13-02-19

Our laundry() function kept running itself until our callstack reached its maximum request limit, or basically exploded like the laundring machine above!

The callstack does alot for us in the background of our app, its where our code is processed. But we need to also give it some guidance, for example:

If you ordered a pizza but gave no directions and no specific details for your pizza to the restaurant, would you expect the pizza to show up on time and with the right toppings?

Of course not, and the callstack has no idea what functions we want processed first and when to process them, it's there to run our functions.

This is why understanding the callstack "hierarchy" is important. As developers we want to have precedence on what order our functions are processed.

My goal for this next example is to visualize why ordering our functions is important if we want the right result and how our functions are entering the callstack, and how they will be able to "exit" the callstack to prevent our washing machine from blowing up.

Lets analyze the code below:

Screenshot from 2019-12-06 13-21-33

On line 12 we invoke decisionB (aka execute the script). All the functions in this script are then sent to our callstack to be processed. If we look into decision B we can see that it relies on decisionA, therefore decision A will need to be processed aswell to return the data we're are relying on for decisionB. How we can make sure decisionA also makes it to the callstack is including it before we execute our script on line 12 this is because JavaScript performs synchronously, meaning, one at a time and "top to bottom". Because we need to use the result of decisionA as data to for our decisionB we need to make sure we invoke decisionA so we can have it added to the callstack.

This is an example of a successfull execution in the callstack and returns our desired message:
"๐˜‰๐˜ถ๐˜บ ๐˜จ๐˜ณ๐˜ข๐˜ฏ๐˜ฏ๐˜บ ๐˜ด๐˜ฎ๐˜ช๐˜ต๐˜ฉ ๐˜ข๐˜ฑ๐˜ฑ๐˜ญ๐˜ฆ๐˜ด, ๐˜ฃ๐˜ฆ๐˜ค๐˜ข๐˜ถ๐˜ด๐˜ฆ ๐˜ต๐˜ฉ๐˜ฆ๐˜บ ๐˜ข๐˜ณ๐˜ฆ ๐˜ต๐˜ฉ๐˜ฆ ๐˜ฃ๐˜ฆ๐˜ด๐˜ต";

So what will happen if we place our decisionA function after we send our script to the callstack from line 12? (example below)

Screenshot from 2019-12-06 13-26-28

We end up with this error because, our decision A is never added to our callstack and therefore cannot be processed by our callstack.

In our last example here we dived a bit deeper into theory. We should hopefully understand why our interface displaying the error "undefined" is not exactly the real reason for script not to run as we intended.

Screenshot from 2019-12-06 13-28-53

I hope after reading this, you've become even a bit more aquainted with what's happening behind the scenes when we invoke our functions.