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

The Functional Manifesto: Fighting Against the State

ksfulton
August 30, 2015

The Functional Manifesto: Fighting Against the State

An introduction to functional programming.

ksfulton

August 30, 2015
Tweet

Other Decks in Technology

Transcript

  1. some background Functional Programming(FP) languages have been around since LISP

    was created in the late 1950s by John McCarthy. In fact, FP predates Object Oriented(OO) programming. However, at that time machine memory was expensive — too expensive to make FP practical, because it requires a lot of memory. Nowadays, memory is absurdly cheap. Functional programs can be implemented easily and FP is becoming increasingly popular.
  2. why functional programming? Functional code is modular which allows us

    to test and debugging, reuse, and generalize code more easily. By being both modular and stateless, purely functional code exercises the design principle of composability. FP makes it easier for code to run concurrently. In short, when well executed, functional code is less prone to bugs.
  3. higher order functions In functional programming, functions are “first class

    citizens,” meaning they can be returned as values or passed as inputs to other functions. A function that does either of those is referred to as a higher order function. Higher order functions are the linchpin of functional programming.
  4. filter Filter is a HOF that takes a predicate (a

    function that tells whether something is true or not) and a list and then returns the list of elements that satisfy that predicate. Scala: val list = List.range(1, 11) def isGreater?(x: Int, upperBound: Int): Boolean = x > upperBound val greaterThanFive = list.filter(x => isGreater?(x, 5)) greaterThanFive is List(6,7,8,9,10)
  5. filter In Ruby: array = *(1..10) greater_than_five = array.select {

    |x| x > 5 } The Procedural Way: def greater_than_five(array) new_array = Array.new array.each { |e| new_array.push(e) if e > 5 } return new_array end
  6. fold Fold is a HOF that builds a single return

    value by operating on a list of values. With the power of higher order functions, you can decide how you want to combine your list. Scala: def sum(accumulator: Int , x: Int) = x + y val total = (0 to 10).foldLeft(0)((acc, x) => sum(acc, x)) total is 55
  7. fold In Ruby: (1..10).inject { | sum, x | sum

    + x } The Procedural Way: total = 0 (1..10).each { |num| total += num } total is 55
  8. map Map is a HOF that applies a given function

    to each element of a list, returning a list of results. Scala: def square(n: Int) = n * n val squaredList = List(1,2,3,4).map{ x => square(x) } squaredList is List(1,4,9,16)
  9. map In Ruby: square = (1..4).map { | x |

    x * x } square is [1,4,9,16] The Procedural Way: def square(array) new_array = Array.new array.each { |x| new_array.push(x * x) } return new_array end
  10. anonymous functions Because higher order functions are so common in

    Scala, the language supports function literals or anonymous functions. def isGreater?(x: Int, upperBound: Int): Boolean = x > upperBound val greaterThanFive = list.filter(x => isGreater?(x, 5)) Becomes... val greaterThanFive = list.filter(_ > 5)
  11. anonymous functions def sum(accumulator: Int , x: Int) = x

    + y val total = (0 to 10).foldLeft(0)((acc, x) => sum(acc, x)) Becomes... val total = (0 to 10).foldLeft(0)( _ + _ )
  12. pure functions The primary tenet of pure FP is that

    programs are constructed using only pure functions —functions that produce no side effects. Some examples of side effects: • Modifying a variable • Modifying a data structure in place • Reading from or writing to a file • Reading or writing to a database
  13. immutable data In pure functional programming values cannot be reassigned

    or altered once created. val x = List(1,2,3,4,5) x.map(i => i * 2) x is List(1, 2, 3, 4, 5) val y = x.map(i => i * 2) y is List(2, 4, 6, 8, 10) x is List(1, 2, 3, 4, 5)
  14. mutable data In Ruby, you can reassign variables as you

    need or want. def square(array) array.each_with_index { |n, index| array[index] = n * n } array end changing_array = Array[1,2,3,4] square(changing_array) changing_array is now Array[1,4,9,16]
  15. the problem with state Mutating state adds a level of

    unpredictability to your code. var counter = 0 def f(x:Int) = { counter = counter + 1 x + counter }
  16. iteration vs. recursion Iteration in functional languages is usually accomplished

    with recursion. def recursiveFact(r: Int): Int = if (r == 1) r else r * recursiveFact(r-1) def loop_fact(n) (2 .. n-1).each { |i| n *= i } return n end
  17. in conclusion OOP/ Procedural (Imperative) Functional (Declarative) What do I

    focus on? Tracking changes in state, performing tasks step by step. How do I transform an input to get the output I want? Does state change? All the time! Nope! Primary flow control Loops, iteration, method calls Recursion, function calls What do I manipulate Classes, instances of classes! I pass functions around!
  18. in conclusion A real live example! (0 to 10000).filter( _

    % 2 == 0 ).map( _ / 2 ).reduce( _ + _ )