logo

Парадигма функціонального програмування

вступ
Функціональне програмування — це парадигма програмування, в якій ми намагаємося пов’язати все в стилі чистих математичних функцій. Це декларативний тип стилю програмування. Його основна увага зосереджена на тому, що потрібно вирішити, на відміну від імперативного стилю, де головна увага полягає в тому, як вирішити. Він використовує вирази замість тверджень. Вираз обчислюється для отримання значення, тоді як оператор виконується для призначення змінних. Ці функції мають деякі особливості, які обговорюються нижче.

Функціональне програмування базується на лямбда-численні:
Лямбда-числення — це структура, розроблена Алонзо Черчем для вивчення обчислень із функціями. Її можна назвати найменшою мовою програмування в світі. Він дає визначення того, що можна обчислити. Все, що можна обчислити за допомогою лямбда-числення, можна обчислити. Він еквівалентний машині Тьюрінга за своєю здатністю обчислювати. Він забезпечує теоретичну основу для опису функцій та їх оцінки. Він є основою майже всіх сучасних функціональних мов програмування.
Факт: Алан Тюрінг був учнем Алонзо Черча, який створив машину Тюрінга, яка заклала основу імперативного стилю програмування.

Мови програмування, які підтримують функціональне програмування: Haskell, JavaScript, Python, Scala, Erlang, Lisp, ML, Clojure, OCaml, Common Lisp, Racket.



Поняття функціонального програмування:

  • Чисті функції
  • Рекурсія
  • Посилальна прозорість. Функції є першокласними та можуть бути змінними вищого порядку. Незмінні.

Чисті функції: Ці функції мають дві основні властивості. По-перше, вони завжди дають однаковий результат для однакових аргументів, незалежно від будь-чого іншого.
По-друге, вони не мають побічних ефектів, тобто вони не змінюють жодних аргументів або локальних/глобальних змінних або потоків введення/виведення.
Пізніше властивість називається незмінністю. Єдиним результатом чистої функції є значення, яке вона повертає. Вони детерміновані.
Програми, створені за допомогою функціонального програмування, легко налагоджувати, оскільки чисті функції не мають побічних ефектів або прихованого введення/виведення. Чисті функції також полегшують написання паралельних/конкурентних програм. Коли код написаний у такому стилі, розумний компілятор може робити багато речей – він може розпаралелювати інструкції, чекати, щоб оцінити результати, коли вони потрібні, і запам’ятовувати результати, оскільки результати ніколи не змінюються, доки не змінюються вхідні дані.
приклад чистої функції:

sum(x, y) // sum is function taking x and y as arguments return x + y // sum is returning sum of x and y without changing them>

Рекурсія: У функціональних мовах немає циклу for або while. Ітерація у функціональних мовах реалізована через рекурсію. Рекурсивні функції постійно викликають самі себе, поки не досягнуть базового випадку.
приклад рекурсивної функції:

fib(n) if (n <= 1) return 1; else return fib(n - 1) + fib(n - 2);>

Посилальна прозорість: У функціональних програмах змінні після визначення не змінюють свого значення протягом усієї програми. Функціональні програми не мають операторів присвоєння. Якщо нам потрібно зберегти якесь значення, ми замість цього визначаємо нові змінні. Це виключає будь-які шанси побічних ефектів, оскільки будь-яку змінну можна замінити її фактичним значенням у будь-якій точці виконання. Стан будь-якої змінної є постійним у будь-який момент.

приклад:

x = x + 1 // this changes the value assigned to the variable x. // So the expression is not referentially transparent.>

Функції є першокласними та можуть бути вищого порядку: Функції першого класу розглядаються як змінна першого класу. Змінні першого класу можна передати функціям як параметр, їх можна повернути з функцій або зберегти в структурах даних. Функції вищого порядку — це функції, які приймають інші функції як аргументи, і вони також можуть повертати функції.

приклад:

show_output(f) // function show_output is declared taking argument f // which are another function f(); // calling passed function print_gfg() // declaring another function print('hello gfg'); show_output(print_gfg) // passing function in another function>

Змінні є незмінними: У функціональному програмуванні ми не можемо змінити змінну після її ініціалізації. Ми можемо створювати нові змінні, але не можемо змінювати існуючі змінні, і це справді допомагає підтримувати стан протягом усього часу виконання програми. Коли ми створили змінну та встановили її значення, ми можемо бути повністю впевнені, знаючи, що значення цієї змінної ніколи не зміниться.

Переваги та недоліки функціонального програмування

Переваги:

  1. Чисті функції легше зрозуміти, оскільки вони не змінюють жодних станів і залежать лише від наданих їм вхідних даних. Незалежно від результату, який вони виробляють, це повертається значення, яке вони дають. Сигнатура їх функції надає всю інформацію про них, тобто тип повернення та аргументи.
  2. Здатність мов функціонального програмування розглядати функції як значення та передавати їх функціям як параметри робить код більш читабельним і зрозумілим.
  3. Тестування та налагодження легше. Оскільки чисті функції приймають лише аргументи та видають вихідні дані, вони не виробляють жодних змін, не приймають вхідні дані та не виробляють прихований вихід. Вони використовують незмінні значення, тому стає легше перевіряти деякі проблеми в програмах, написаних із використанням чистих функцій.
  4. Він використовується для реалізації паралелізму/паралелізму, оскільки чисті функції не змінюють змінні чи будь-які інші дані поза ним.
  5. Він використовує відкладене обчислення, яке дозволяє уникнути повторного обчислення, оскільки значення оцінюється та зберігається лише тоді, коли це необхідно.

Недоліки:

  1. Іноді написання чистих функцій може зменшити читабельність коду.
  2. Написання програм у рекурсивному стилі замість використання циклів може трохи лякати.
  3. Написати чисті функції легко, але поєднати їх з рештою програми та операціями вводу/виводу є складним завданням.
  4. Незмінні значення та рекурсія можуть призвести до зниження продуктивності.

Застосування:

  • Використовується в математичних обчисленнях.
  • Він необхідний там, де потрібен паралельність або паралелізм.

Факт: Whatsapp потребує лише 50 інженерів для свого 900M користувачів тому що Erlang використовується для реалізації своїх потреб у паралельності. Facebook використовує Haskell у своїй системі захисту від спаму.