Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Programming, A Primer

Kaung Htet
December 20, 2014

Functional Programming, A Primer

Kaung Htet

December 20, 2014
Tweet

More Decks by Kaung Htet

Other Decks in Technology

Transcript

  1. • Give an idea on wtf is functional paradiagm •

    The fundamental concepts & features • Functional features in other “regular” languages
  2. • Expressions, not statements • let x = 1;; int

    = 1 • let add x y = x + y;; int -> int -> int = <fun> • let add x = (fun y -> x + y);; int -> int -> int = <fun> • let doStuff f x = (f x) + 1;; ('a -> int) -> 'a -> int = <fun> • Immutability by default • Functions are first class
  3. • Functions and methods can have side effects. • Pass

    in a data structure by its reference and you update it.
  4. • Functions and methods can have side effects. • Pass

    in a data structure by its reference and you update it. • By the time the function returns a result, the original data structure has been changed.
  5. • Functions and methods can have side effects. • Pass

    in a data structure by its reference and you update it. • By the time the function returns a result, the original data structure has been changed. total = 0 for i in range(len(someSeq)): total = total + someSeq[i]
  6. total = 0; for (x = 1; x <= n;

    x++) { total = total + x*x; }
  7. total = 0; for (x = 1; x <= n;

    x++) { total = total + x*x; } let rec sumsq n = if n=0 then 0 else sumsq n*n + sumsq(n-1);;
  8. total = 0; for (x = 1; x <= n;

    x++) { total = total + x*x; } let rec sumsq n = if n=0 then 0 else sumsq n*n + sumsq(n-1);; let rec sumof f n = if n=0 then 0 else f n + sumop f (n-1);;
  9. let rec sumof f n = if n=0 then 0

    else f n + sumop f (n-1);;
  10. let rec sumof f n = if n=0 then 0

    else f n + sumop f (n-1);; let sumsquares x = sumof square x;;
  11. let rec sumof f n = if n=0 then 0

    else f n + sumop f (n-1);; let sumsquares x = sumof square x;; let sumcubes x = sumof cube x;;
  12. let rec sumof f n = if n=0 then 0

    else f n + sumop f (n-1);; let sumsquares x = sumof square x;; let sumcubes x = sumof cube x;; let sumcubes = sumof (fun x → x*x*x);;
  13. let rec fib n = match n with | 0

    -> 1 | 1 -> 1 | n -> fib(n-1) + fib (n-2);;
  14. let rec fib n = match n with | 0

    -> 1 | 1 -> 1 | n -> fib(n-1) + fib (n-2);; let rec fib’ n = let rec aux n a b = if n <= 0 then a else aux (n-1) (a+b) a in aux n 1 0;;
  15. let rec fib n = match n with | 0

    -> 1 | 1 -> 1 | n -> fib(n-1) + fib (n-2);; let rec fib’ n = let rec aux n a b = if n <= 0 then a else aux (n-1) (a+b) a in aux n 1 0;; fib 4 aux 4 1 0 aux 1 3 2 aux 2 2 1 aux 3 1 1 aux 0 5 3 8
  16. • Converting a single function of n arguments -> n

    functions with a single argument. • λ(x,y).z ⟶ λ x.(λ y. z) • function f(x,y,z) { z(x(y)); } • function f(x) { lambda (y) { lambda (z) { z(x(y)); }
  17. • The shapes of our data • Checked before run-time/at

    compile-time • In advanced languages, automatically inferred • Rules as to what pieces can validly fit together • e.g., 1 + “1” does not make sense. • Can build proofs of correctness
  18. fact 0 = 1 fact n = n * fact

    (n-1) [A x|A x <- [A 1, B 1, A 2, B 2]] -> [A 1, A 2] let rec fib n = match n with | 0 -> 1 | 1 -> 1 | n -> n + fib (n-1);;
  19. Work for custom defined types as well type color =

    Red | Blue | Green;; type ‘a tree = Leaf of ‘a | Node of ‘a tree * ‘a tree;; let r = { num = 3; denom = 4};; let ratio_to_float r = match r with | {num = n; denom = v} -> (float_of_int n) /. (float_of_int v);;
  20. Functions as first-class citizens • Like data structures, functions should

    be first-class: • It has a value and type • Passed as arguments • Can be constructed at runtime • Stored inside data structures • More abstraction, more generic program code
  21. Map • Applies the parameter function to every element of

    the list List.map - : ('a -> 'b) -> 'a list -> 'b list = <fun>
  22. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys)
  23. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys) let rec prod xs = match xs with | [] -> 1 | y::ys -> y * (sum ys)
  24. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys) let rec prod xs = match xs with | [] -> 1 | y::ys -> y * (sum ys) let map f xs = let rec aux xs = match xs with | [] -> [] | y::ys -> (f y)::(aux ys) in aux xs ;;
  25. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys) let rec prod xs = match xs with | [] -> 1 | y::ys -> y * (sum ys) let map f xs = let rec aux xs = match xs with | [] -> [] | y::ys -> (f y)::(aux ys) in aux xs ;; map (+) [1;2;3];;
 map (*) [1;2;3];;
  26. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys) let rec prod xs = match xs with | [] -> 1 | y::ys -> y * (sum ys) let map f xs = let rec aux xs = match xs with | [] -> [] | y::ys -> (f y)::(aux ys) in aux xs ;; map (+) [1;2;3];; map (*) [1;2;3];;
  27. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys) let rec prod xs = match xs with | [] -> 1 | y::ys -> y * (sum ys) let map f xs = let rec aux xs = match xs with | [] -> [] | y::ys -> (f y)::(aux ys) in aux xs ;; let double xs = map (fun x -> 2*x) xs let is_pos xs = map (fun x -> x>0) xs map (+) [1;2;3];; map (*) [1;2;3];;
  28. let rec sum xs = match xs with | []

    -> 0 | y::ys -> y + (sum ys) let rec prod xs = match xs with | [] -> 1 | y::ys -> y * (sum ys) let map f xs = let rec aux xs = match xs with | [] -> [] | y::ys -> (f y)::(aux ys) in aux xs ;; let double xs = map (fun x -> 2*x) xs let is_pos xs = map (fun x -> x>0) xs map (+) [1;2;3];; map (*) [1;2;3];;
  29. Filter • Select a subset of the list that satisfies

    the given predicate List.filter : ('a -> bool) -> 'a list -> 'a list = <fun>
  30. let filter p xs = let rec aux xs =

    match xs with | [] -> [] | y::ys -> if (p y) then y::(aux ys) else aux ys in aux xs
  31. let filter p xs = let rec aux xs =

    match xs with | [] -> [] | y::ys -> if (p y) then y::(aux ys) else aux ys in aux xs let keep_pos xs = filter (fun x -> x>0) [-3;-2;-1;0;1;2];; # int list = [1;2] let smaller n xs = filter (fun x -> String.length x<=n) 3 [“myatnoe”; “ocaml”; “xxxx”];;
  32. Folding • Reduce the list down to one value applying

    the given function over and over.
  33. Folding • Reduce the list down to one value applying

    the given function over and over. List.fold_left: ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun>
  34. Folding • Reduce the list down to one value applying

    the given function over and over. List.fold_left: ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun> List.fold_right- : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b = <fun>
  35. foldr :: (a -> b -> b) -> b ->

    [a] -> b foldr f v [] = v foldr f v (x:xs) = f x (foldr f v xs) sum [1, 2, 3] = foldr (+) 0 [1,2,3] = foldr (+) 0 (1:(2:(3:[]))) = 1+(2+(3+0)) = 6
  36. sum [] = 0 sum (x:xs) = x + sum

    xs product [] = 1 product (x:xs) = x * product xs and [] = True and (x:xs) = x && and xs or [] = False or (x:xs) = x || or xs sum = foldr (+) 0 l product = foldr (*) 1 l and = foldr (&&) True or = foldr (||) False
  37. • Invented by Alonzo Church in 1941 • Foundational language

    beneath a lot of functional langauges (e.g., Lisp, Haskell ..)
  38. • Invented by Alonzo Church in 1941 • Foundational language

    beneath a lot of functional langauges (e.g., Lisp, Haskell ..) • Caputres core aspects of computation
  39. • Invented by Alonzo Church in 1941 • Foundational language

    beneath a lot of functional langauges (e.g., Lisp, Haskell ..) • Caputres core aspects of computation • Turing complete
  40. • Invented by Alonzo Church in 1941 • Foundational language

    beneath a lot of functional langauges (e.g., Lisp, Haskell ..) • Caputres core aspects of computation • Turing complete • Discusses a lot of reduction/evaluation strategies, fundamental concepts, currying, church booleans (λx. λy.x, λx. λy.y), function pairs, church numerals, typing .,etc
  41. • Invented by Alonzo Church in 1941 • Foundational language

    beneath a lot of functional langauges (e.g., Lisp, Haskell ..) • Caputres core aspects of computation • Turing complete • Discusses a lot of reduction/evaluation strategies, fundamental concepts, currying, church booleans (λx. λy.x, λx. λy.y), function pairs, church numerals, typing .,etc • In its simplest universal form, there is untyped lambda calculus.
  42. Alpha renaming • Equivalent up to bound variable renaming. •

    e.g., λ x.x = λ y.y, • λ y.x y = λ z.x z • But NOT:
 λ y. x y = λ y. z y
  43. Beta Reduction • Evaluates to the body of the abstraction

    with parameter substitution • e.g., (λ x. x y) z ⟶ᵦ z y • (λ x. y) z ⟶ᵦ y • (λ x . x x)(λ x . x x) ⟶ᵦ (λ x . x x)(λ x . x x)
  44. Evaluation strategies Full beta reduction (λx.x)((λx.x)(λz.(λx.x)z)) (λx.x)((λx.x)(λz.z)) (λx.x)(λz.z) λz.z Normal

    order • (λx.x)((λx.x)(λz.(λx.x)z)) • (λx.x)(λz.(λx.x)z) • λz.(λx.x)z • λz.z Call by name • (λx.x)((λx.x)(λz.(λx.x)z)) • (λx.x)(λz.(λx.x)z) • λz.(λx.x)z Call by value • (λx.x)((λx.x)(λz.(λx.x)z)) • (λx.x)(λz.(λx.x)z) • λz.(λx.x)z .,etc etc
  45. • Strict languages evaluates all arguments to functions before entering

    call. (Call by value) e.g., C, Java, ML • Non-strict languages will enter function call and only evaluate the arguments as they are required. (Call by name). Lazy languages like Haskell by default will use call-by-need.
  46. • The Lambda Calculus - http://plato.stanford.edu/entries/lambda-calculus/ • A Tutorial Introduciton

    to Lambda Calclus - http://www.inf.fu-berlin.de/lehre/ WS03/alpi/lambda.pdf • Introduction to Lambda Calculus - http://www.cse.chalmers.se/research/group/ logic/TypesSS05/Extra/geuvers.pdf
  47. Javascript • “Scheme with no brackets” • Higher Order functions

    • Closures • Partial Applications • Composition • Type systems in js compilers • Lambda functions • underscore.js, lodash.js
  48. Python • List comprehensions • First class functions • Higher

    order functions (map, reduce, filter) • Immutable data types • Lazy evaluation with generators • functools, itertools
  49. • Many classical algorithms only specified imperatively • Many classical

    data structures only specified imperatively • Culture • JVM problems • Lack of support for full tail call optimization requires more workarounds • funarg problem
  50. • Great UIs? Purescript, Elm, Clojurescript • Theory? PLT, Type

    Systems, Type Theory • Ease maintenance? Proofs with types, property tests • DRY? Recursion schemes, Category Theory • Algorithms? Pearls, Odaski • Concurrency? Erlang
  51. Take what I’ve shared today, and make it your own

    “Make Functional Programming Yours”