Functional Programming
Tags: javascript, webdev, beginners, programming
Published: 2022-10-10 09:38:49

In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions.

Functional programming (also called FP) is **a way of thinking about software construction by creating pure functions**. It avoid concepts of shared state, mutable data observed in Object Oriented Programming. Functional languages empazies on expressions and declarations rather than execution of statements.

Functional programming is **a style of programming that emphasizes the evaluation of expressions, rather than execution of commands**. The expressions in these languages are formed by using functions to combine basic values. A functional language is a language that supports and encourages programming in a functional style.

**Mainly the functional programming is the way of coding in expressions instead of coding in statements.**

**→ Function Expression vs Function Statement.**

```jsx
// Function Statement..
function sayName(){
	console.log('I am Rakhiyaatul Kubra');
}

// Function Expression..
const sayName2 = () => {
	console.log('I am Expression of Function');
};
```

- Pure Function + Side Effects + Immutability.
- Function Composition.
- Higher Order Function ( HOF ).
- Function Scope + Closure + Hoisting.
- Callback Function.
- IIFE (Immediately Invoked Function Expression).

## Pure Function + Side Effects + Immutability

→ Pure Function.

```jsx
// Pure Function..
function sum(a, b) {
  return a + b;
}

sum(10, 30); // 30
```

→ Side Effects.

It should not change the Mutable data. Cause of global scope of variable.

```jsx
// Side Effects..
let limit = 100;

function changeLimit(limit){
  limit = 500;
  return limit;
}

changeLimit(limit);
console.log(limit); // 100
```

⇒ When it’s time to give without param. So it’s becomes the Impure function😃. And that is the side effect.

```jsx
// Side Effects..
let limit = 100;

function changeLimit(){
  limit = 500;
  return limit;
}

changeLimit(limit); // 500
console.log(limit);
```

⇒ Pure function without Side Effect.

```jsx
const arr = [1, 2, 3];

function add(data){
	arr.push(data);
}
```

→ And using of **console.log()** is also the Side Effect in the Function.

## Function Composition.

Function composition is **an approach where the result of one function is passed on to the next function, which is passed to another until the final function is executed for the final result**. Function compositions can be composed of any number of functions.

```jsx
// Simple example of function composition..
function r1(a, b){
	return a + b;
}

function r2(a, b){
	return a - b;
}

function times(a, b){
	return a * b;
}

let num1, num2, callStack;
num1 = 20; num2 = 5;
callStack = times(r1(num1, num2), r2(num1, num2));

console.log(callStack);
```

## Higher Order Function ( HOF )

⇒ Function can be passed as an argument.

⇒ Function can be return from another function.

### Hidden Concepts.

- Scope
- Closure
- Function Context

**→ Example of HOF.**

```jsx
function hFn(a, b){
	const sum = a + b;
	return sum;
}
```

→ Without **HOF** (Higher Order Function) Concept.

```jsx
// Without Higher Order Function..
// Sum..
function sum(num1, num2, max = 100) {
  const rand1 = Math.floor(num1) * max;
  const rand2 = Math.floor(num2) * max;
  return rand1 + rand2;
}

// Sub..
function sub(num1, num2, max = 200) {
  const rand1 = Math.floor(num1) * max;
  const rand2 = Math.floor(num2) * max;
  return rand1 - rand2;
}

// Mul..
function mul(num1, num2, max = 10) {
  const rand1 = Math.floor(num1) * max;
  const rand2 = Math.floor(num2) * max;
  return rand1 * rand2;
}

sum(10, 20); // 3000
sub(30, 10); // 4000
mul(30, 20); // 60000
```

> We did the easy and normal mode coding which is not very effective and not so efficient to clients. When they wants new feature and then it’s gone to break down or time consuming.
> 

→ Little bit better than before.

```jsx
// Without Higher Order Function..
// Random Numbers..
function genarateRandoms(num1, num2, max){
  const rand1 = Math.floor(num1) * max;
  const rand2 = Math.floor(num2) * max;
  return {rand1, rand2};
}

// Sum..
function sum(num1, num2, max = 100) {
  const { rand1, rand2 } = genarateRandoms(num1, num2, max);
  return rand1 + rand2;
}

// Sub..
function sub(num1, num2, max = 200) {
  const { rand1, rand2 } = genarateRandoms(num1, num2, max);
  return rand1 - rand2;
}

// Mul..
function mul(num1, num2, max = 10) {
  const { rand1, rand2 } = genarateRandoms(num1, num2, max);
  return rand1 * rand2;
}

sum(10, 20); // 3000
sub(30, 10); // 4000
mul(30, 20); // 60000
```

> It’s great but not the Higher Order Function. We have to make this into the HOF for perfect example to understand what is Higher Order Function.
> 

### Function can be passed as an argument

⇒ Finally with **HOF ( Higher Order Function ).**

```jsx
// With Higher Order Function..
function genarateTwoRandomNumbers(max, cb){
	const random1 = Math.floor(Math.random() * max);
	const random2 = Math.floor(Math.random() * max);
	const result = cb(random1, random2);
	return result;
}

// Sum..
genarateTwoRandomNumbers(100, (rand1, rand2) => {
	return rand1 + rand2;
});

// Sub..
genarateTwoRandomNumbers(10, (rand1, rand2) => rand1 - rand2);

// Mul..
genarateTwoRandomNumbers(20, (rand1, rand2) => rand1 * rand2);
```

> The perfect example of HOF Higher Order Function. And It follows ⇒ Function can be passed as an argument. Also known as CallBack Function.
> 

### Function can be return from another function

⇒ Now let’s see how functions can be return from another function.

```jsx
// Function returns the another function..
const power = (p) => {
  return (n) => {
    let result = 1;
    for (let i = 1; i <= p; i++){
      result = result * n;
    }
    return result;
  };
};

const sqr = power(2);
const cube = power(3);

console.log('Square of 2 -> ', sqr(2));
console.log('Square of 3 -> ', sqr(3));

console.log('Cube of 2 -> ', cube(2));
console.log('Cube of 3 -> ', cube(3));
```

> A function returns another function, and there is the functions sequence. It follows ⇒ Function can be return from another function.
> 

→ Another way of doing this.

```jsx
// Function returns the another function..
const power = (p) => {
  const operation = (n) => {
    let result = 1;
    for (let i = 1; i <= p; i++){
      result = result * n;
    }
    return result;
  };
  return operation;
};

const sqr = power(2);
const cube = power(3);

console.log('Square of 2 -> ', sqr(2));
console.log('Square of 3 -> ', sqr(3));

console.log('Cube of 2 -> ', cube(2));
console.log('Cube of 3 -> ', cube(3));
```

> We can working with return the functions statements rather-then returning full function.
> 

→ Also we can call like this way — **power()(); → power(powerArg.)(operationArg.);**

```jsx
// Function returns the another function..
const power = (p) => {
  const operation = (n) => {
    let result = 1;
    for (let i = 1; i <= p; i++){
      result = result * n;
    }
    return result;
  };
  return operation;
};

console.log('Square of 4 -> ', power(2)(4)); // 16
console.log('Cube of 2 -> ', power(3)(2));   // 8
```

→ And this is the Normal way of doing the things. Without functional programming.

```jsx
// Sqrt..
const sqr = (n) => {
  return n * n;
};

// Cube..
const cube = (n) => {
  return n * n * n;
};

console.log('Square of 2 -> ', sqr(2));
console.log('Square of 3 -> ', sqr(3));

console.log('Cube of 2 -> ', cube(2));
console.log('Cube of 3 -> ', cube(3));
```

> This is the example without functional programming.
> 

### Function Context / Execution Context

⇒ Function or, Execution Context here. It follows the Stack Data Structure’s concept.

```jsx
// The Execution Context..
/// our coding contest here...
function A(){
  console.log('I am A');
}

function B(){
  A();
}

function C(){
  B();
  B();
}

function D(){
  C();
  A();
}

D();
```

> This CallStack Function Context will show you with VS-Code **(Run and Debug)** if you are using with easy way. And it’s totally understanding things, without understanding you will not able to know how the functions callStack actually works and what is the Execution Context of functions.
> 

## Function Scope + Closure + Hoisting

The function scope is the block of statements, where codes are secure & safe into the scope. When the statement is not exists into current scope so it’s should search for it’s parent scope as well. 

**→ JavaScript Lexical Scoping.**

A lexical scope in JavaScript means that **a variable defined outside a function can be accessible inside another function defined after the variable declaration**. But the opposite is not true; the variables defined inside a function will not be accessible outside that function.

When the statement is not exists its own scope so it should search for it’s parent then again if not found? Again it’s try to searching it’s parents → parents as well. Then we call this is Lexical Scoping in JavaScript.

```jsx
// Example of Lexical Scoping..
function main(){
	let num1 = 5;

	function childFunc(){
		console.log(num1);
	}
}
```

### **JavaScript Closure**

In JavaScript, a closure is **a function that references variables in the outer scope from its inner scope**. The closure preserves the outer scope inside its inner scope. To understand the closures, you need to know how the lexical scoping works first.

A closure is a function that preserves the outer scope in its inner scope.

**⇒ Example 01.**

```jsx
/// Example 01 of Closure..
function greeting(){
	let message = 'Hi';
	
	function sayHi(){
		console.log(message);
	}
	return sayHi;
}

let hi = greeting();
hi(); // still can access the message variable
```

**⇒ Example 02.**

```jsx
/// Example 02 of closure..
function greeting(message){
	return function(name){
		return message + ' ' + name;
	}
}

let sayHi = greeting("Hi dear, ");
let sayHello = greeting("Hello dear, ");

console.log(sayHi("Asad")); // Hi dear, Asad
console.log(sayHello("Akhiyaat")); // Hello dear, Akhiyaat
```

### Hoisting of JavaScript

→ When you declared the function or variable after execution or definition, so it’s called hoisting. When you declare a function and you call the function before declaring it, it calls hoisting.

**⇒ Example**

```jsx
// Hoisting..
func();

function func(){
	console.log(test);
}

var test = 'Something';

func();
```

> undefined
> 

> Something
> 

## Callback Function.

A callback function is **a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.**

```jsx
// Example of CallBack function..
function sayName(name){
  console.log(`My name is ${name}`);
}

function takeUsername(callBack){
  const userName = prompt('Please enter your name : ');
  callBack(userName);
}

takeUsername(sayName);
```

→ Or this way.

```jsx
// Example of CallBack function..
function takeUsername(callBack){
  const userName = prompt('Please enter your name : ');
  callBack(userName);
}

takeUsername(function(name){
  console.log(`My name is ${name}`);
});
```

## IIFE (Immediately Invoked Function Expression)

An Immediately-invoked Function Expression (IIFE for friends) is **a way to execute functions immediately, as soon as they are created**. IIFEs are very useful because they don't pollute the global object, and they are a simple way to isolate variables declarations.

we can declaring IIFE with 3 ways.

- IIFE.
- Arrow Function IIFE.
- async IIFE.

**→ IIFE.**

```jsx
// IIFE..
(function(name){
  console.log(`I am ${name}`);
})('Samantha');
```

**→ Arrow Function IFFE.**

```jsx
// Arrow Function IIFE..
((name) => {
  console.log(`I am ${name}`);
})('Rakhiyaat');
```

**→ async IIFE.**

```jsx
// async IIFE..
(async function(){
	console.log('hello');
})();

(async function(){
	console.log('Hello');
})();
```

**Resources:**

[Functional Programming: Concepts & Advantages](https://hackr.io/blog/functional-programming)

[9 Functional Programming Concepts Everyone Should Know | HackerNoon](https://hackernoon.com/9-functional-programming-concepts-everyone-should-know-uy503u21)