В информатике функциональное программирование — это парадигма программирования, в которой программы создаются путем применения и составления функций.

Функциональное программирование (также называемое ФП) — это способ создания программного обеспечения путем создания чистых функций. Он позволяет избежать концепций общего состояния и изменяемых данных, наблюдаемых в объектно-ориентированном программировании. Функциональные языки ориентированы на выражения и объявления, а не на выполнение операторов.

Функциональное программирование – это стиль программирования, в котором упор делается на вычисление выражений, а не на выполнение команд. Выражения в этих языках формируются с помощью функций для объединения основных значений. Функциональный язык — это язык, который поддерживает и поощряет программирование в функциональном стиле.

В основном функциональное программирование – это способ написания выражений вместо написания операторов.

→ Выражение функции и оператор функции.

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

// Function Expression..
const sayName2 = () => {
   console.log('I am Expression of Function');
};
  • Чистая функция + побочные эффекты + неизменяемость.
  • Функциональная композиция.
  • Функция высшего порядка (HOF).
  • Область действия функции + Закрытие + Подъем.
  • Функция обратного вызова.
  • IIFE (выражение функции с немедленным вызовом).

Чистая функция + побочные эффекты + неизменяемость

→ Чистая функция.

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

sum(10, 30); // 30

→ Побочные эффекты.

Он не должен изменять данные Mutable. Причина глобальной области видимости переменной.

// Side Effects..
let limit = 100;

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

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

⇒ Когда пора давать без парам. Итак, это становится нечистой функцией😃. И это побочный эффект.

// Side Effects..
let limit = 100;

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

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

⇒ Чистая функция без побочных эффектов.

const arr = [1, 2, 3];

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

→ И использование console.log() также является побочным эффектом в функции.

Функциональная композиция.

Композиция функций — это подход, при котором результат одной функции передается следующей функции, которая передается другой до тех пор, пока последняя функция не будет выполнена для окончательного результата. Функциональные композиции могут состоять из любого количества функций.

// 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);

Функция высшего порядка (HOF)

⇒ Функцию можно передавать в качестве аргумента.

⇒ Функция может быть возвращена из другой функции.

Скрытые концепции.

  • Объем
  • Закрытие
  • Контекст функции

→ Пример HOF.

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

→ Без концепции HOF (функции высшего порядка).

// 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

Мы сделали простой и обычный режим кодирования, который не очень эффективен и не очень эффективен для клиентов. Когда им нужна новая функция, а она сломалась или отнимает много времени.

→ Немного лучше, чем раньше.

// 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

Это здорово, но не функция высшего порядка. Нам нужно превратить это в HOF, чтобы получить идеальный пример, чтобы понять, что такое функция высшего порядка.

Функция может быть передана в качестве аргумента

⇒ Наконец, с помощью HOF (функция высшего порядка).

// 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);

Идеальный пример функции высшего порядка HOF. Из этого следует ⇒ Функция может быть передана в качестве аргумента. Также известна как функция обратного вызова.

Функция может быть возвращена из другой функции

⇒ Теперь давайте посмотрим, как можно вернуть функцию из другой функции.

// 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));

Функция возвращает другую функцию, и есть последовательность функций. Отсюда следует ⇒ Функция может быть возвращена из другой функции.

→ Другой способ сделать это.

// 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));

Мы можем работать с возвратом операторов функций, а не с возвратом полной функции.

→ Также мы можем вызвать так — power()(); → мощность(powerArg.)(operationArg.);

// 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

→ И это нормальный способ ведения дел. Без функционального программирования.

// 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));

Это пример без функционального программирования.

Контекст функции/контекст выполнения

⇒ Здесь функция или контекст выполнения. Это соответствует концепции структуры данных стека.

// 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();

Этот контекст функции CallStack покажет вам VS-код (Запуск и отладка), если вы используете простой способ. И это полное понимание вещей, без понимания вы не сможете узнать, как на самом деле работают функции callStack и каков контекст выполнения функций.

Область действия функции + Закрытие + Подъем

Область действия функции — это блок операторов, коды которого надежно защищены и помещаются в область действия. Если оператор не существует в текущей области, ему следует также выполнить поиск в родительской области.

→ Лексическая область видимости JavaScript.

Лексическая область видимости в JavaScript означает, что переменная, определенная вне функции, может быть доступна внутри другой функции, определенной после объявления переменной. Но обратное неверно; переменные, определенные внутри функции, не будут доступны вне этой функции.

Когда оператор не имеет собственной области действия, поэтому он должен снова искать своего родителя, если не найден? Опять пытается найти своих родителей → родителей тоже. Тогда мы называем это лексической областью видимости в JavaScript.

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

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

Закрытие JavaScript

В JavaScript замыкание — это функция, которая ссылается на переменные во внешней области из внутренней области. Замыкание сохраняет внешнюю область внутри внутренней области. Чтобы понять замыкания, вам нужно сначала знать, как работает лексическая область видимости.

Замыкание — это функция, которая сохраняет внешнюю область видимости во внутренней области.

⇒ Пример 01.

/// 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

⇒ Пример 02.

/// 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

Поднятие JavaScript

→ Когда вы объявили функцию или переменную после выполнения или определения, это называется подъемом. Когда вы объявляете функцию и вызываете ее перед ее объявлением, она вызывает подъем.

⇒ Пример

// Hoisting..
func();

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

var test = 'Something';
func();

не определено

Что-то

Функция обратного вызова.

Функция обратного вызова — это функция, передаваемая в другую функцию в качестве аргумента, которая затем вызывается внутри внешней функции для выполнения какой-либо процедуры или действия.

// 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);

→ Или вот так.

// 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 (выражение функции с немедленным вызовом)

Выражение функции с немедленным вызовом (IIFE для друзей) — это способ немедленного выполнения функций сразу после их создания. IIFE очень полезны, поскольку они не загрязняют глобальный объект и представляют собой простой способ изолировать объявления переменных.

мы можем объявить IIFE тремя способами.

  • ИИФЭ.
  • Стрелочная функция IIFE.
  • асинхронный IIFE.

→ IIFE.

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

→ Функция стрелки IFFE.

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

→ асинхронный IIFE.

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

(async () => {
 console.log('Hello');
})();

Ресурсы:

Функциональное программирование: концепции и преимущества

9 концепций функционального программирования, которые должен знать каждый | ХакерПолдень