FP / Úvod

Funkcionálne programovanie

Sergej Chodarev (sergejx.net)

Čo je to FP?

Paradigmy programovania

Procedurálne programovanie

function factorial(n) {
    var fact = 1;
    for (var i = 1; i <= n; i++) {
        fact *= i;
    }
    return fact;
}

Funkcionálne programovanie

function factorial(n) {
   return (n == 1) ? 1
                   : n * factorial(n - 1);
}

Rozdiel

Príklad

Funkcia, ktorá zistí, či všetky slova v zozname majú nepárny počet znakov.

function allOdd(words) {
    var result = true;
    for (var i = 0; i < words.length; i++) {
        var len = words[i].length;
        if (!odd(len)) {
            result = false;
            break;
        }
    }
    return result;
}
function allOdd(words) {
    return reduce(and, map(compose(odd, length), words));
}

Funkcia vyššieho rádu

Funkcia, ktorej argumentom alebo výsledkom je funkcia.

Java

boolean allOdd(List<String> words) {
    Function<Integer, Boolean> odd = (n) -> n % 2 == 1;
    return words.stream().map(odd.compose(String::length))
                         .reduce(Boolean::logicalAnd)
                         .get();
}

Haskell

allOdd :: [String] -> Bool
allOdd words = and (map (odd . length) words)

Prečo to potrebujeme?

Použitie

Začiatky

Kalkul Lambda

LISP

Scheme

Medzitým v Európe…

Dnes

a väčšina ostatných jazykov

Haskell

Haskell

Použitie

Definícia funkcie

square x = x * x
add a b = a + b

Použitie funkcie

plusThree x = add x 3

Podmienky

max x y | x >= y    = x
        | otherwise = y
-- alebo
max x y
    | x >= y    = x
    | otherwise = y

Rekurzia

factorial n
    | n == 1 = 1
    | n >= 1 = n * factorial (n-1)

Definície typov

factorial :: Int -> Int
factorial n
    | n == 1 = 1
    | n >= 1 = n * factorial (n-1)
max :: Int -> Int -> Int
max a b | a >= b    = a
        | otherwise = b

Entice

(1, "ahoj", True)
fst (x, y) = x  -- pattern matching
snd (x, y) = y

Zoznamy

aList = [1, 1, 2, 3, 5, 8, 13, 21]
sum []     = 0
sum (x:xs) = x + sum xs

Vnorené funkcie

quad a b c | discr == 0 = [-b/(2*a)]
           | discr >  0 = [-(b + sqrt discr) / (2*a),
                           -(b - sqrt discr) / (2*a)]
    where discr = b^2 - 4*a*c