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

Functional Programming - Javascript Focus

Functional Programming - Javascript Focus

Functional paradigm in Javascript

Paulo Mateus

October 07, 2016
Tweet

More Decks by Paulo Mateus

Other Decks in Programming

Transcript

  1. Summary • Pure Functions • callback • Higher-Order Functions •

    Arrow function • Currying • map, filter, forEach, reduce • Destructuring assignment • Recursive functions • Function composition • Generators • Array comprehensions • ...
  2. (Not) Pure Functions var number = 1; function increment() {

    number += 1; } > number 1 > increment(); > number 2
  3. callback var ifce = document.querySelector("#ifce"); function helloWorld() { alert("Hola mundo");

    } ifce.addEventListener("click", helloWorld); var ifce = document.querySelector("#ifce"); ifce.addEventListener("click", function() { alert("Hola mundo"); });
  4. Higher-Order Functions “Matematicamente falando, funções que operam sobre outras funções

    ou as recebendo como parâmetro ou as retornando são chamadas de Higher-Order Functions.”
  5. Arrow function ( ) => { } λ var ifce

    = document.querySelector("#ifce"); var helloWorld = () => alert("Hola mundo"); ifce.addEventListener("click", helloWorld);
  6. function add(a, b) { return a + b; } var

    add = function(a, b) { return a + b; } Currying function add(a) { return function(b) { return a + b; } }
  7. > add(2, 3); 5 Currying > add2 = add(2) >

    add2(3) 5 > (add(2))(3) 5 > add(2)(3) 5
  8. add = a => b => a + b; >

    add(2)(3) 5 Currying (with arrow functions)
  9. [ ].map() [ ].filter() [ ].forEach() [2, 3, 5].map(a =>

    add2(a)) .filter(a => a < 6) .forEach(a => console.log(a))
  10. map = f => array => array.map(f) filter = f

    => array => array.filter(f) Currying • map • filter
  11. > [1, 2, 3, 4].reduce((total, number) => total + number);

    10 > sum = array => array.reduce((total, number) => total + number); > sum([1, 2, 3, 4]) 10 [ ].reduce() using λ
  12. Recursive functions var sum = function(elements) { [head, ...tail] =

    elements; if (elements.length == 1) return head; return head + sum(tail); } > sum([1,2,3,4,5]) 15 > sum([ ]) Uncaught RangeError: Maximum call stack size exceeded(…)
  13. Recursive functions var sum = function(elements) { [head, ...tail] =

    elements; if (elements.length == 1) return head; return head + sum(tail); } > sum([1,2,3,4,5]) 15 > sum([ ]) Uncaught RangeError: Maximum call stack size exceeded(…)
  14. Recursive functions var sum = function([head, ...tail]) { if (tail.length

    == 0) return head; return head + sum(tail); } > sum([1,2,3,4,5]) 15 > sum([ ]) undefined
  15. Recursive functions - foldr - not curry function foldr(fn, last,

    xs) { if (xs.length == 0) return last; [x, ...xs] = xs; return fn(x, foldr(fn, last, xs)); } > sumNumbers = (a, b) => a+b; > foldr(sumNumbers, 0, [1,2,3,4]) 10 > sum = foldr(sumNumbers, 0) ERROR
  16. Recursive functions - foldr - curry? function foldr(fn, last) {

    return (xs) => { if (xs.length == 0) return last; [x, ...xs] = xs; return fn(x, foldr(fn, last)(xs)); } } > sumNumbers = (a, b) => a+b; > sum = foldr(sumNumbers, 0) > sum([1, 2, 3, 4]) 10 > sum([ ]) 0
  17. Recursive functions - foldr - curry var foldr = fn

    => last => xs => { if (xs.length == 0) return last; [x, ...xs] = xs; return fn(x)(foldr(fn)(last)(xs)); } > sum = foldr(a => b => a+b)(0); > sum([1, 2, 3, 4]) 10 > sum([ ]) 0
  18. Function composition . (dot) var compose = (f, g) =>

    x => f(g(x)); // map, filter and sum already defined var even = number => number % 2 == 0; var squared = number => number ** 2; var sumsqreven = compose(sum, compose(map(squared), filter(even))) > sumsqreven([1, 2, 3, 4]) 20
  19. Function composition . (dot) var even = number => number

    % 2 == 0; var squared = number => number ** 2; var sum = (total, element) => total + element; > [1, 2, 3, 4].filter(even) .map(squared) .reduce(sum); 20
  20. Generators (Lazy Lists) function* naturals() { let i = 0

    while (true) yield i++ } > nats = naturals(); > nats.next().value; 0 > nats.next().value; 1 > nats.next().value; 2
  21. Generators (Lazy Lists) for (number of naturals()) { if (number

    < 5) break; console.log(number); } 0 1 2 3 4
  22. Generators (Lazy Lists) interval = begin => function* (end) {

    for (var i = begin; i <= end; i++) yield i; } for (number of interval(0)(5)) console.log(number); 0 1 2 3 4
  23. Generators (Lazy Lists) // exists [1..5] in js? > sumsqreven(interval(1)(5))

    Uncaught TypeError: array.filter is not a function(…) > interval(1)(5) Generator {...} > [...interval(1)(5)] [1, 2, 3, 4] > sumsqreven([...interval(1)(5)]) 20
  24. Array comprehensions - non standart > concat = xss =>

    [for (xs of xss) for (x of xs) x] > concat([[1, 2, 3, 4], [9, 2, 5]]) [ 1, 2, 3, 4, 9, 2, 5 ] [for (x of iterable) x] [for (x of iterable) if (condition) x] [for (x of iterable) for (y of iterable) x + y]
  25. > factors = n => [for (i of interval(1)(n)) if

    (n % i == 0) i]; > factors(15) [ 1, 3, 5, 15 ] > arraysEqual = a => b => JSON.stringify(a) == JSON.stringify(b) // arranjo técnico > prime = n => arraysEqual (factors(n)) ([1, n]) > prime(7) true Array comprehensions - non standart
  26. > primes = n => [for (i of interval(1)(n)) if(prime(i))

    i]; > primes(30) [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ] Array comprehensions - non standart
  27. References http://thiagoalvesifce.getforge.io/disciplinas/2016-1/lip/lip.html Can I use - http://caniuse.com/ MDN - https://developer.mozilla.org

    Functional programming in Javascript: map, filter and reduce Entendendo Programação Funcional em JavaScript de uma vez JavaScript Functional Programming Cookbook (ES6) Lazy lists em JavaScript!