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

Why Functional Programming

Why Functional Programming

Presented Star City Code School

Joe R. Smith

May 13, 2016
Tweet

More Decks by Joe R. Smith

Other Decks in Programming

Transcript

  1. Impera've Programming Computa(on is performed through successive muta(on of state

    via statements. • Based on the Von Neumann computer architecture • Models implementa6on details of the computer (or what the computer used to be) • program variables ↔ computer storage cells • control statements ↔ computer test-and-jump instruc6ons • assignment statements ↔ fetching, storing instruc6ons • expressions ↔ memory reference and arithme6c instruc6ons.
  2. Impera've Programming Problems • Close coupling of seman1cs to state

    transi1on • Poorly suited to concurrent and parallel computa1on • Lacks a useful founda1on fom which to reason about computa1on • correctness, testability, etc.
  3. Impera've Programming Some Impera*ve languages - C 1 - Java

    2 - JavaScript 3 - Ruby 4 - C++ 5 5 object oriented with mul2ple inheritence, sta2c typing, technically weak typing, and a specifica2on full of contradi2ons (see picture, right) 4 object oriented, dynamic typing, strong typing 3 prototypical object oriented, dynamic typing, weak/duck typing 2 object oriented, sta0c typing, strong typing 1 procedural, sta/c typing, weak typing
  4. Impera've Programming Example: inner product int calc_inner_product(int[] a, int[] b,

    int dim) { int c = 0; for(int i = 0; i < dim; ++i) { c = c + a[i] * b[i]; } return c; }
  5. Impera've Programming Example: inner product • Operates on invisible state

    • Dynamic and repe55ve; to understand it you must mentally execute it • Computes the result word-at-a-5me by repe55on of assignment and modifica5on • Entangles housekeeping opera5ons with the rest of the code, making them impossible to extract and reuse
  6. Func%onal inner product Clojure (reduce + (map * a b))

    Haskell foldr (+) 1 (zipWith (*) a b) Ruby a.zip(b).map {|x| x.reduce(:*)}.reduce(:+)
  7. #javascript is a func/onal language the same way my sedan

    is a truck– I use it to haul things around, but it wasn’t built for it.
  8. OOP Matrix Mul,plica,on public class Matrix { int n; int

    m; double[,] a; public Matrix(int n, int m) { if (n <= 0 || m <= 0) throw new ArgumentException("Matrix dimensions must be positive"); this.n = n; this.m = m; a = new double<n, m>; } //indices start from one public double this<int i, int j> { get { return a[i - 1, j - 1]; } set { a[i - 1, j - 1] = value; } } public int N { get { return n; } } public int M { get { return m; } } public static Matrix operator*(Matrix _a, Matrix b) { int n = _a.N; int m = b.M; int l = _a.M; if (l != b.N) throw new ArgumentException("_a.M must be equal b.N"); Matrix result = new Matrix(_a.N, b.M); for(int i = 0; i < n; i++) for (int j = 0; j < m; j++) { double sum = 0.0; for (int k = 0; k < l; k++) sum += _a.a[i, k]*b.a[k, j]; result.a[i, j] = sum; } return result; } }
  9. Before we go any further Lisp expression syntax in one

    slide Instead of this: foo(1, 2, bar(3, 4)); This: (foo 1 2 (bar 3 4))
  10. Func%onal Matrix Mul%plica%on (defn dot-product [x y] (reduce + (map

    * x y))) (defn transpose [coll] (apply map vector coll)) (defn matrix-mult [mat1 mat2] (map (fn [row] (map (partial dot-product row) (transpose mat2))) mat1))
  11. Func%onal Programming6 • Composed of expressions • First-class func6ons •

    Pure func6ons • Immutable data • Value-based equality seman6cs 6 There are many more features common to FP languages, but these are the essen7als.
  12. Composed of expressions • No Statements • No assignment, control

    structures, or explicit return • Programs are expressed by composing func%ons together • No explicit intermediate state
  13. What's wrong with Statements? • They are not composable •

    You cannot pass them as arguments to a func6on • You cannot build higher abstrac6ons from them • No formal “algebra” by which to op6mize or evaluate the correctness of programs. • statements cannot be reduced (operate on hidden state) • None of their uses are unique to statements • usually used to approximate expression composi6on in an impera6ve way.
  14. We don't need statements if(predicate, then, else) Takes a predicate

    expression and, if true, returns the result of evalua6ng the then expression; otherwise, returns the result of evalua6ng the else expression eq(a, b) If a is func)onally equivalent to b, returns true; otherwise, false
  15. Expression Algebra if(a, eq(x, b), eq(x, c)) ≡ eq(x, if(a,

    b, c)) This is possible because if is an expression and expressions adhere to simple, well-defined rules of composi9on
  16. First-class Func-ons Func%ons are a primi%ve en%ty type in the

    language • Func&ons can be passed as arguments to other func&ons • Higher Order func&ons: • Func&ons that take func&ons as arguments or return func&ons as results
  17. Higher Order Func.ons (defn make-adder [n] (fn [x] (+ n

    x))) (map (make-adder 3) [1 2 3 4]) result: [4 5 6 7]
  18. Higher Order Func.ons (defn prime? [num] (let [p (fn [x]

    (= (mod num x) 0))] (not (some p (range 2 num))))) (def count-if (comp count filter)) (count-if prime? (range 3000)) result: 432
  19. Laziness Higher order func.ons make lazy evalua.on possible: The range

    func)on produces a lazy-sequence of all posi)ve integers. (def all-primes (filter prime? (range))) (take 20 all-primes) result: [0 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61]
  20. Pure Func)ons A rela'on between a set of inputs and

    a set of poten'al outputs with the property that each input is related to exactly one output. • Implies no side-effects • Enables referen%al transparency • an expression can be replaced with its value without changing the behavior of a program • Makes many op7miza7ons possible (e.g., memoiza7on) • Work hand-in-hand with immutable data
  21. Immutable Data Data that cannot be modified a/er it is

    created • New values are func%ons of old values • Values can always be observed and new values calculated from old values without coordina8on • Values will never change "in hand" • Values can be safely shared between threads • No need for defensive copying (or any copying)
  22. Persistent Immutable Datastructures Immutable data structures that share structure under

    the hood • safe to do share data between data- structures because all data is immutable • Unreachable data can be garbage- collected at op7mal granularity • Crea7ng new data-structures from exis7ng ones requires li=le or no copying of member data
  23. State, Iden*ty, and Value • Values don't change (if they

    did, they'd be different values) • e.g., 72, {–, ‖, —, ―}, "cat", [2, 3, 5, 7] • An IdenGty is an enGty that is associated with different values over Gme • State is a value at a point in Gme • IdenGGes give us conGnuity across state changes
  24. Func%onal Programming is Inevitable • Virtually every mainstream language has

    been adding or seen widespread adop7on the aforemen7oned features at an increasingly rapid pace • Java Lambdas • Ruby Lazy Sequences • JavaScript ImmutableJS • For the past 50+ years impera7ve languages have been slowly adding func7onal features • Adding func7onal features to impera7ve languages is a double-edged sword (complexity, sub-op7mal implementa7on)
  25. Try a Func*onal Language • Wri%ng func%onal code in a

    func%onal language, rather than using a func%onal style in an impera%ve language is: • Simpler, and o;en easier • Allows you to lean on features (e.g., pure func%ons and immutable data) • O;en more performant (e.g., persistent immutable datastructures)
  26. Try a Func*onal Language Haskell - Purely func0onal, sta0cally-typed (ML

    family) Clojure - (mostly) Purely func4onal, dynamically-typed, runs on the JVM and JavaScript VMs (Lisp family) F# - sta(cally-typed, runs on .net run(me (OCaml Family)