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