Javascript: Functional Programming
Tags: javascript, functional
Published: 2021-05-10 06:05:44

Functional Programming (FP) is a paradigm used for build computer applications applying and composing pure functions without mutating the state and data. It is also a declarative type of programming that implements the logic of process without explaining its control flow. It makes use of expressions instead of statements.

There's some concepts that are needed to be understood if FP will be applied:

* [Pure functions](#pure-functions)
* [Immutable data](#immutable-data)
* [Referencial transparency](#referencial-transparency)
* [First class functions](#first-class-functions)
* [High order functions](#high-order-functions)
* [Recursion over loops](#recursion-instead-of-loops)

### Pure functions <a name="pure-functions"></a>

A pure function has two principal characteristics: 

**1. A function that given the same inputs, return the same output. For Example:**

```javascript
const double = x => x * 2

console.log(double(4)) // 8
console.log(double(4)) // 8
console.log(double(4)) // 8
```

As you can see, when the function `double` is called with the same parameter (in this case 4), it always return the same result.

Not all functions fulfill this specification. This are some examples of functions that are not pure:

```javascript
Math.random() // 0.9475128240189292
Math.random() // 0.1712299774003645
Math.random() // 0.16032971104683935

(new Date()).getTime() // 1620616533928
(new Date()).getTime() // 1620616539849
(new Date()).getTime() // 1620616541638
```

In this case, the functions `random` and `getTime` aren't pure, because given the same parameters are not returning the same value.

**2. It has no side-effects. This means that functions are not going to change any arguments, global variables or do some kind of I/O.**

```javascript
const animals = ["cat", "dog", "cow"]

const addSheepAnimal = (animalsArray) => {
  animalsArray.push('sheep')

  return animalsArray
}

const newAnimals = addSheepAnimal(animals)

console.log(newAnimals) // [ 'cat', 'dog', 'cow', 'sheep' ]
console.log(animals) // [ 'cat', 'dog', 'cow', 'sheep' ]
```

In the example above, the function `addSheepAnimal` has side effect over the `animalsArray` parameter, because is changing the array that is pass when the function is called. In order to fix this, the array should be clone inside the function so it has no side effects.

```javascript
const animals = ["cat", "dog", "cow"]

const addSheepAnimal = (animalsArray) => {
  return [...animalsArray, 'sheep']
}

const newAnimals = addSheepAnimal(animals)

console.log(newAnimals) // [ 'cat', 'dog', 'cow', 'sheep' ]
console.log(animals) // [ 'cat', 'dog', 'cow' ]
```

### Immutable data <a name="immutable-data"></a>

Data is immutable when values of javascript structures cannot be changed once are assigned. This means when a variable is already assigned, the value can't be change in coming parts of the flow. 

It's a good practice always use `const` declaration instead of `var` and `let` so mutable data can be avoid. But we must have caution with arrays and objects in order to not change the pointer reference, is recommended to clone the object/array once is passed as parameter in the functions if a change needs to be made on them, and then return the new object.

### Referencial transparency <a name="referencial-transparency"></a>

The sum of `Pure Functions` plus `Immutable Data` returns `Referencial Transparency`. The function are not going to modify any global variables, and only will work with their scope variables. Once the function returns a value, it will be assigned to a new variable. Example:

```javascript
const number = 3;

const square = x => x ** 2;

const result = square(number)

console.log(result) // 9
```

### First-class functions <a name="first-class-functions"></a>

`First-class functions` are functions that are treated as variables and can be passed to another functions as arguments.

```javascript
const numbers = [2, 5, 3, 8, 10];

const double = (x) => x * 2;

const doubleNumbers = numbers.map(double);

console.log(doubleNumbers) // [ 4, 10, 6, 16, 20 ]
```

In the example above, the `double` function is considered as `first-class function` because is treated as variable, and also is being passed in the `map` function.

### High order functions <a name="high-order-functions"></a>

`High-order functions` are functions that accept another functions as arguments or returns a function as an output.

Array procedures like `map`, `reduce` or `filter` are considered as `high-order functions`. Also, methods can be created that match this definition.

### Recursion instead of loops <a name="recursion-instead-of-loops"></a>

In functional programming is needed to avoid using loops, because they are required to change the state outside their scope for the purpose to finish the cycles.

```javascript
// Loop

let loopSum = 0
const loopLimit = 15

for (let i = 0; i <= loopLimit; i++) {
   loopSum += i;
}

console.log(loopSum) // 120


// Recursion

const recLimit = 15

const sumNum = (val, lim) => {
  if(val <= lim) {
    return val + sumNum(val + 1, lim)
  }

  return 0
}

console.log(sumNum(0, recLimit)) // 120
```
In this previous script, we did both loop and recursion example. We can notice how loop change the global variable `loopSum` in every cycle. Instead the recursive way not changed any state that didn't belong to its scope.

## Wrapping up

I hope you enjoyed this information about functional programming in JavaScript with me! For some it may be a new programming paradigm, but I hope you will try to use it. I think your applications will be easier to read and debug. If you have any suggestions, comments or questions, let me know in the comments. Thanks!