Напоследък четох много статии, говорещи за Функционално програмиране (FP), след което реших да обобщя какво научих, като написах тази статия.

Преди да хвърлите куп концепции тук, знаете ли какво е функционално програмиране? Това е парадигма за разработка на софтуер, която става все по-известна сред разработчиците. Идеята е да кодирате просто и чисто, като избягвате странични ефекти, като използвате силата на функциите.

Уикипедия дефинира функционалното програмиране като

… парадигма на програмиране — стил на изграждане на структурата и елементите на компютърните програми — който третира изчислението като оценка на математически функции и избягва променящо се състояние и променливи данни — Wikipedia

Повечето от статиите, които прочетох, засягат следните теми.

  • Чисти функции;
  • Неизменност;
  • Референтна прозрачност;
  • Функционира като първокласни субекти;
  • Функции от по-висок порядък (HOF);

Вярвам, че е важно да разберете концепциите, споменати преди, защото може да използвате FP и дори да не знаете. Да ги разберете е от съществено значение за подобряване на качеството на вашия код. И така, да преминем към понятията.

Чисти функции

Може би се питате кои сачистите функции? как създавате или определяте дали дадена функция е чиста или не?

Чистите функции винаги връщат едни и същи резултати, когато са дадени едни и същи входове. Следователно те нямат странични ефекти. Чистите функции позволяват референтна прозрачност, което означава, че можете да замените извикване на функция с получената от нея стойност. — „Коуди Арсено“

Е, въз основа на препратката по-горе можем да дефинираме чиста функция като нещо детерминистично. Написах прост пример по-долу.

Можем ли да го считаме за чиста функция? Не можем да го считаме за пример за чиста функция поради използваната глобална променлива, която не е предадена като параметър. Въпреки това, можем да го поправим, като предадем глобалната променлива като параметър, но аз предпочитам да го напиша по-долу.

Някои примери за нечисти функции са тези, които четат външни файлове, генерират произволни числа. Това се дължи на изхода, който може да е различен дори при извикване на тези функции, предаващи едни и същи параметри.

// It generates a value given a minimum and a maximum value
function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min;
}
getRandomArbitrary(1, 10);
getRandomArbitrary(1, 10);

Като се има предвид това, можем да заключим, че използвайки концепцията за чисти функции, кодът става по-лесен за тестване и не е нужно да се подиграваме на нищо.

  • При даден параметър w очаквайте функцията да върне стойност x
  • При даден параметър y очаквайте функцията да върне стойност z

Неизменност

Способността да останеш същият във времето при всякакви обстоятелства

Данните са неизменни, когато състоянието им не може да се промени след създаването им. Не можете да промените неизменен обект. Вместо това трябва да създадете нов обект с новата стойност. Следващият пример е често срещана ситуация, при която хората могат да преработят своя код, за да следват принципите на неизменността.

Рекурсиятае чудесен начин да се избегне променливостта в итерациите. Пренаписвайки кода по-горе, можем да имаме нещо като по-долу.

Функцията sum получава масива products и се извиква, докато получим празен масив. За всяка итерация ще добавим цената на продукта към общата сума. В крайна сметка имаме сумирането на цените, а също и неизменните променливи.

Референтна прозрачност

Референтната прозрачност е концепцията за еднакъв изход, когато използваме един и същ вход. Например, имайки следната чиста функция.

const cube = (number) => number * number * number;

Извиквайки го три пътипреминавайки числото четири, винаги ще получаваме 64 като резултат. Така че можем да заменим cube(4)с 64. Следователно можем да потвърдим, че референтната прозрачност е резултат от написването на чиста функция, която има неизменни данни.

Функционира като първокласни обекти

Идеята зад функциите като първокласни обекти е, че трябва да третираме функция като стойност и да я използваме като данни. Когато възприемем тази гледна точка, можем да започнем дасе позоваваме на нея от константи и променливи, също да я предаваме като параметър на други функции и дори да я връщаме като резултат от други функции. Връщайки се към нашия пример за рекурсия, можем да имаме две нови функции, totalAfterTaxes и applyDiscount5.

Както можете да видите, ние използваме функции като аргумент. Създаваме верига за изпълнение, която премахва необходимостта от създаване на променливи за съхраняване на резултатите, които да се предават в другите функции.

Функции от по-висок порядък (HOF)

Дефиницията на функция от по-висок ред е функция, която приема една или повече функции като аргументи или връща функция като резултат.

Тези нови функции, реализирани по-горе, са пример за функции от по-висок ред. Ако сте запознати с JavaScript, може да сте чували за функциите филтриранеи карта. Те са често срещан пример за функции от по-висок ред. Нека да разгледаме някои примери.

Филтър

Да предположим, че искаме всички продукти под $2. Можем да използваме филтърната функция, за да оценим друга функция и ако резултатът е trueда съхраним елемента в нов масив.

Карта

Методът map може да трансформира колекция чрез прилагане на функция към всички нейни елементи и създаване на нова колекция от върнатите стойности. Ако искаме да удвоим цената на тези продукти, можем да направим нещо като примера по-долу.

Моето заключение

След като прочетох много статии и написах тази статия, смятам, че парадигмата на функционалното програмиране (FP) е чудесен начин за кодиране на приложения, които могат да бъдат тествани и без грешки. Надявам се да ви предам малко за моето разбиране за FP.

Забележка: Това беше първата ми статия на английски, така че се извинявам за всякакви граматически грешки 😅