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

Functional Programming - A Gentle Introduction

Functional Programming - A Gentle Introduction

What is Functional Programming? Let's break down some of its core characteristics, and learn how using these techniques can make you a better programmer.

Bruno Abrantes

February 06, 2015
Tweet

More Decks by Bruno Abrantes

Other Decks in Programming

Transcript

  1. Transforming Data • OO is about modelling hierarchies and maintaining

    state • But the real world is not about holding state, it’s about shifting state. • It’s Doing Things instead of Talking About Things
  2. Imperative Programs • Programmed using sequential statements • Statements change

    program state, encouraging side effects • Focused on how things are accomplished
  3. //dogs = [{name: 'Fido', owner_id: 1}, {...}, ... ] //owners

    = [{id: 1, name: 'Bob'}, {...}, ...] var dogsWithOwners = [] var dog, owner for(var di=0; di < dogs.length; di++) { dog = dogs[di] for(var oi=0; oi < owners.length; oi++) { owner = owners[oi] if (owner && dog.owner_id == owner.id) { dogsWithOwners.push({ dog: dog, owner: owner }) } }} }
  4. Declarative Programs • Programmed using expressions • Are referentially transparent,

    causing no side effects • Focused on what is accomplished
  5. Side Effects • Anything that alters the world as a

    result of executing a function • In FP, functions are referentially transparent, which means that, given an input x, the output will always be y
  6. Immutability • Values are guaranteed to remain the same throughout

    the program • Makes concurrency a lot easier • You change a value by copying it instead of mutating it
  7. # "world" is directly mutated by "add_person" world.add_person(person) # an

    immutable reference "world" is injected into the function # "add_person" returns a copy of "world" with "person" added to it # the original "world" ref remains safe! world = add_person(world, person)
  8. First Class Functions • A function is just a value

    • Can be stored anywhere • Can be anonymous
  9. Higher Order Functions • Functions can be passed to other

    functions • A Function can be returned from a function
  10. function makeGreeting(name) { var greeting = "Hello, "; function greetName()

    { return greeting + name; } return greetName; } var myGreeting = makeGreeting('Babbel'); myGreeting() // -> "Hello, Babbel"
  11. Composition • Combines simple functions to build more complex ones

    • Like in Mathematics, the result of each function is passed to the next • The result of the last function is the result of the whole
  12. # Haskell foo = f . g # Elixir foo

    = f |> g First Class Composition
  13. var compose = function () { var args = arguments;

    var start = args.length - 1; return function() { var i = start; var result = args[start].apply(this, arguments); while (i--) result = args[i].call(this, result); return result; }; } var f = compose(negate, square, mult2, add1); f(2); // -> 9 Bring yo’ own composition Javascript
  14. module Funkify class ::Proc def |(other) Funkify.compose(other, self) end end

    def compose(*args) head, *tail = args head = _procify(head) if args.size <= 2 ->(*xs) { head.(_procify(tail[0]).(*xs)) } else ->(*xs) { head.(compose(*tail)) } end end def _procify(obj) case obj when Symbol method(obj).to_proc else obj.to_proc end end end (mult(5) | add(1) | negate).(3) #=> -16 Bring yo’ own composition Ruby
  15. For your looping consideration • Most of your time is

    spent handling Collections • Applicative Functors (-_-)’ cover most of your needs • each, map, reduce, select, reject, take, zip, …
  16. var square = function (x) { return Math.pow(x, 2); };

    var values = [1, 2, 3, 4, 5]; var newValues = []; for(var i=0; i < values.length; i++) { newValues.push(square(values[i])); } newValues // -> [1, 4, 9, 16, 25] Map Transforms a list into another list using a function
  17. var square = function (x) { return Math.pow(x, 2); };

    var values = [1, 2, 3, 4, 5]; newValues = values.map(square); // -> [1, 4, 9, 16, 25] Map Transforms a list into another list using a function
  18. var sum = function (a, b) { return a +

    b }; var values = [1, 2, 3, 4, 5]; var sumOfValues = 0; for(var i=0; i < values.length; i++) { sumOfValues = sum(sumOfValues, values[i]); } sumOfValues // -> 15 Reduce/Fold/Inject “Folds” a list into a single value, using an accumulator
  19. var sum = function (a, b) { return a +

    b }; var values = [1, 2, 3, 4, 5]; sumOfValues = values.reduce(sum, 0); // -> 15 Reduce/Fold/Inject “Folds” a list into a single value, using an accumulator
  20. var isEven = function (x) { return x % 2

    == 0 }; var values = [1, 2, 3, 4, 5]; var evenValues = []; for(var i=0; i < values.length; i++) { if (isEven(values[i])) { evenValues.push(values[i]); } } evenValues // -> [2, 4] Filter/Select Returns values that pass a truth test
  21. var isEven = function (x) { return x % 2

    == 0 }; var values = [1, 2, 3, 4, 5]; evenValues = values.filter(isEven); // -> [2, 4] Filter/Select Returns values that pass a truth test
  22. values .filter(isEven) .map(square) .reduce(sum, 0); // -> 20 Everyday I’m

    composin’ Lets take these values and get the sum of the squares of all the even ones!
  23. Lazy Evaluation • An evaluation strategy which delays the evaluation

    of an expression until its final value is needed • Avoids repetitive evaluation (as in the previous example) • You can potentially construct infinite data structures (Streams say “hi!”)
  24. Recursion • Using Pattern Matching techniques, you can recurse through

    a list to process it • Because of immutability, laziness and tail-call optimization, recursing tends to be much more performant than in imperative languages
  25. def map([], _func) do [] end def map([ head |

    tail ], func) do [func.(head) | map(tail, func)] end Let’s implement Map! In an actual functional language, Elixir :)
  26. Easier reasoning is good • more modular code • more

    testable code • less bugs to wake you up at 2AM
  27. So where do I sign up? • You’re probably already

    doing some of this • Try a functional language! • Don’t fear the Mathspeak (explain me Monads one more time…)
  28. Some cool libraries • Lodash, Ramda, Bacon.js (Javascript) • Prelude

    (Ruby) • Swiftz (Swift) • ObjectiveSugar (Objective-C)