The Power of Pure Functions: Making Your Code More Predictable and Maintainable

The Power of Pure Functions: Making Your Code More Predictable and Maintainable

Table of contents

No heading

No headings in the article.

In this blog, we are going to learn about some of the javascript functions related topics that are mainly asked in interviews but we also use these in our day-to-day code.

  1. Pure Functions: The function which has no side effects and is given the same input always returns the same output then these functions are known as Pure

    Functions. So to understand it better we need to understand two things first what we mean by NO SIDE EFFECTS and second GIVEN THE SAME INPUT

    IT ALWAYS RETURNS THE SAME OUTPUT. Let's understand it by example.

     // FIRST WE WILL SEE NORMAL FUNCTIONS
     let counter = 0;
     function increaseCount(){
       counter++;
      return counter;
     }
    

    You see in the above function we are directly mutating the outer scope variable and we are not passing the counter as an argument of incrementCount() function because whenever you call that function it will increase the count of the outer variable counter means this function has side effects and that why it, not the pure function.

    One of the disadvantages of that incrementCount() function not being pure is that it can make your code harder to understand and debug. If you have a bug in your code that causes unexpected state changes, it can be difficult to determine which function is responsible for the problem because that counter variable can be used by 10 other functions also and this way now we may have to debug all these functions where ever we are using the counter variable.

     // Converting incrementCount function to pure function
     function incrementCount(counter) {
       return counter + 1;
     }
    
     let counter = 0;
     counter = incrementCount(counter); // counter is now 1
     counter = incrementCount(counter); // counter is now 2
     counter = incrementCount(counter); // counter is now 3
    

    Here we need to understand that you can still modify the counter variable outside of the incrementCount() function, which means that the function itself is not completely pure. However, by making the incrementCount() function pure, we've isolated the state modification to a single function and made it easier to reason about and debug.
    Given the example, suppose that you have a large codebase with many different functions that modify the counter variable. If you use the impure version of incrementCount() along with other impure functions, it can be difficult to track down bugs and understand how the counter variable is changing over time.
    Overall, making the incrementCount() function pure doesn't eliminate the possibility of modifying the counter variable outside of the function, it can still be a useful technique for improving the maintainability and predictability of your code. Let's see some of the real-world examples of a pure function that we use in our day-to-day coding.

     // YEP Math.max() Math.min() these are the pure functions
     Math.max(3, 5, 11,2); // returns 11
    

    This function is pure because it doesn't modify any variables outside of its local scope, and its behaviour is completely determined by its input parameters. No matter how many times you call Math. max() with the same input values, it will always return the same result. There are more great examples of pure functions that we use most of the time like map, filter and reduce these all the pure functions also let's see one of them with an example.

     // Lets see example of map function
     const numbers = [1,4,8];
     const tripled = numbers.map(num => num * 3);
     console.log(tripled); // returns [3,12,24];
    

    In this example, the map() method creates a new array tripled that contains the result of tripling each element of the original numbers array. The input array is not modified, and the behaviour of map() is only determined by the input array and the function num => num * 3 that is passed as an argument there are no side

    effects to this function and no matter how many times you call this function given the same array input it will always return us the same output. Let's see one last example which is a bit tricky and maybe sometimes asked in interviews also.

     // Question to you is printSomething() is pure function or not?
       function printSomething(){
          console.log("No experts but just trying");
       }
    

    And here the answer is no printSomething() is not a pure function because It performs a side effect of printing a message to the console, which changes the state of the environment outside the function. Pure functions should not perform side effects or modify any state outside their scope, but should only depend on their input parameters to produce an output.

    ONE LAST QUESTION CAN EVERY FUNCTION CAN BE A PURE FUNCTION?

    And the answer is no in practical not all functions can be pure functions because, in our day-to-day coding, we have to connect lots of external stuff like writing read and write files, connecting with API using fetch and managing global state these all require us to have those side effect that being said, writing pure functions is a good practice as it makes the code more predictable and easier to reason about, which can make the code more testable and maintainable but it's not possible to have all the functions as pure functions.

That's all about Async vs Defer in JavaScript. And thanks to Akshay Saini for creating an incredible playlist this blog is just whatever learning I had from there.