# Understanding pure functions in javascript

Pure functions allow us to get a predictable result every time they are been invoked. They find its applications in redux, functional programming. Hence in order for a  function to be classified as pure, it must fulfill certain rules: 

1)  Given the same arguments, it returns the same result:
let us illustrate this

```
const sum = (a, b) => a + b 
sum(1, 3) // 4
sum(1, 3) // 4
sum(4, 2) // 6
sum(4, 2) // 6

``` 
looking at `sum` produces the same result, when we pass the same argument to it, `sum` satisfies the first rule of pure function.

 
2) Pure function does not produce side effects:- sides effects could be mutating external state, logging(e.g console.log), API request, I/O operations.


```
const sumWithLog = (a, b) => {
console.log(a, b)
return a+b
}

const arr = [2, 3, 4];
const addToArr = (arr, a) => { 
arr.push(a);
return arr;
}
console.log(addToArr(arr, 5)) // [2, 3, 4, 5];
console.log(addToArr(arr, 5)) // [2, 3, 4, 5, 5];
``` 
Looking at `sumWithLog` it technically violates the second rule by definition despite it obeys the first rule, while `addToArr` is not also a pure function because it's mutating external state. let's make impure `addToArr` to become  pure by adjusting the code,


```
const arr = [2, 3, 4];
const addToArr = (arr, a) => {
const arrCopy = [...arr]  //  line 1
arrCopy.push(a);
return arrCopy;
}
console.log(arr) // [2, 3, 4] 
console.log(addToArr(arr, 5)) // [2, 3, 4, 5];
console.log(addToArr(arr, 5)) // [2, 3, 4, 5]
console.log(arr) // [2, 3, 4] 
``` 
Looking at the code snippet above, `addToArr` obeys our first rule and second rule, our result is now predictable. At line 1 we make a copy of `arr` by spreading `arr` elements which gave us the capability to not mutate the original `arr`. it's also important to note that spread operator does shallow copying of values.

3) Pure functions depends only on the arguments passed to them. What this actually means is a pure function is self-contained, it does not depend on values outside its scope to determine its final value.
let's illustrate this:

```
const b = 6
const sum1 = (a) => (a + b) //  line 1 
const sum2 =  (a, b = 1) => (a + b) line // 2
``` 
`sum1` is considered an impure function because it takes value outside its scope to determine the final result which could be changed. The value of `b` in sum1 could easily be changed by external code which makes the function to unpredictable. `sum2` corrects the defect in `sum1`.

Hence for a function to consider a pure function, the three rules above must all be satisfied, violation of any automatically makes the function impure.
 Finally, pure functions make our code more predictable and testable.




