Functional programming
Лямбда-обчислення
формальна система, що використовується в теоретичній кібернетиці для дослідження визначення функції, застосування функції, та рекурсії.
(Машина Тьюрінга для функціонального програмування)
Лямбда-числення уникає станів, воно має справу з функціями, котрі отримують значення параметрів та повертають результати обчислень (можливо, інші функції), але не спричиняють до зміни вхідних даних (сталість).
Що? Чому? Коли?
Функціональне програмування — парадигма програмування, яка розглядає програму як обчислення математичних функцій та уникає станів та змінних даних. Функційне програмування наголошує на застосуванні функцій, на відміну від імперативного програмування, яке наголошує на змінах в стані та виконанні послідовностей команд.
Функціональне програмування - по суті, практична реалізація лямбда обчислень.
Концепція не нова
В 1958 в МІТ було розроблено мову Lisp, але через низьку доступність пам'яті і її дороговизну не знайшла практичного застосування

Як визначити функціональне програмування?
- не мають станів та змінних
- можуть мати функції вищих порядків, функції першого класу: замикання, рекурсія
- розширюється нечіткими (лінивими) обчисленнями, монадами
Стан
1; // value
int x = 1; // x is an id that has value
x = x + 1; // now x changed state
public class Square {
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
System.out.println(i + ": " + i * i);
}
}
}Stateless?
System.out.println(1 + ": " + 1 * 1);
System.out.println(2 + ": " + 2 * 2);
System.out.println(3 + ": " + 3 * 3);
...
public class Squares {
public static void main(String[] args) {
printSquares(20);
}
private static void printSquares(int i) {
if (i > 0) {
printSquares(i - 1);
System.out.println(i + ": " + i * i);
}
}
}Stateless
Проблема станів

Функції вищого порядку
int add(int i, int j) {
return i + j;
}class add_function_t {
int add(int i, int j) {
return i + j;
}
}
add_function_t add = new add_function_t(); void handleMessage(Message msg) {
// ...
msg.setClientCode("ABCD_123");
// ...
sendMessage(msg);
}
// ...
}1.
2.
class MessageHandler {
void handleMessage(Message msg) {
// ...
if(msg.getDestination().equals("server1") {
msg.setClientCode("ABCD_123");
} else {
msg.setClientCode("123_ABC");
}
// ...
sendMessage(msg);
}
// ...
}abstract class MessageHandler {
void handleMessage(Message msg) {
// ...
msg.setClientCode(getClientCode());
// ...
sendMessage(msg);
}
abstract String getClientCode();
// ...
}
class MessageHandlerOne extends MessageHandler {
String getClientCode() {
return "ABCD_123";
}
}
class MessageHandlerTwo extends MessageHandler {
String getClientCode() {
return "123_ABCD";
}
}class MessageHandler {
void handleMessage(Message msg, Function getClientCode) {
// ...
Message msg1 = msg.setClientCode(getClientCode());
// ...
sendMessage(msg1);
}
// ...
}
String getClientCodeOne() {
return "ABCD_123";
}
String getClientCodeTwo() {
return "123_ABCD";
}
MessageHandler handler = new MessageHandler();
handler.handleMessage(someMsg, getClientCodeOne);Недоліки
- Відсутність гарантування прямого порядку обчислень
Як позбутись недоліків?
continuation monads uniqueness typing- Pattern matching
clojure
Монади

val list = List("One", "Two")
list.map(value => value + " 1")
.map(value => value + " 2")list: List[String] = List(One, Two)
res0: List[String] = List(One 1 2, Two 1 2)
-
Каррирування (currying)
-
Ліниві обчислення
-
Нескінченні структури даних
Інші структури
Переваги
- простіше в написанні й підтримці
- багатопоточність
- легше тестувати
- оновлення без зупинки всієї системи
- доведені обчислення і оптимізація (Machine Assisted Proofs and Optimizations)
Представники
- Erlang
- Lisp
- R
- Haskell
Scala Clojure - Scheme
- F#
Functional programming
By Sania Sutula
Functional programming
- 444