Skip to content

Latest commit

 

History

History
259 lines (179 loc) · 5.85 KB

README.md

File metadata and controls

259 lines (179 loc) · 5.85 KB

Livro de receitas - Programação Funcional em JavaScript (ES6)

Um livro de receitas para escrever programação funcional no JavaScript com ES6.

Índice

Funções puras

Retorna o mesmo valor se passado os mesmos parâmetros. Sua execução não depende do estado do sistema.

  1. Função impura
let number = 1;

const increment = () => number += 1;

increment();
// 2
  1. Função pura
const increment = n => n + 1;

increment(1);
// 2

O que são "Higher-order functions"

São funções que operam em outras funções, seja por receber elas como argumentos ou retornando-a como valor.

  1. Função de soma
const sum = (x, y) => x + y;

const calculate = (fn, x, y) => fn(x, y);

calculate(sum, 1, 2);
// 3
  1. Filtrando elementos
let students = [
    {name: 'Anna', grade: 6},
    {name: 'John', grade: 4},
    {name: 'Maria', grade: 9}
];

const isApproved = student => student.grade >= 6;

students.filter(isApproved);
// [ { name: 'Anna', grade: 6 }, { name: 'Maria', grade: 9 } ]
  1. Map
const byName = obj => obj.name;

students.map(byName);
// [ 'Anna', 'John', 'Maria' ]
  1. Encadeando funções
let students = [
    {name: 'Anna', grade: 6},
    {name: 'John', grade: 4},
    {name: 'Maria', grade: 9}
];

const isApproved = student => student.grade >= 6;

const byName = obj => obj.name;

students.filter(isApproved).map(byName);
// ['Anna', 'Maria']
  1. Usando reduce
const totalGrades = students.reduce((sum, student) => sum + student.grade, 0);

totalGrades
// 19

Recursão

Sempre que uma função chama a si mesmo, criando um loop.

  1. Função de contagem regressiva
const countdown = num => {
  console.log(num)
  num < 1
  ? num
  : countdown(num - 1)
}

countdown(5);
/*
5
4
3
2
1
0
*/
  1. Calculando uma fatorial
const factorial = (num) =>
  num <= 0
  ? 1
  : n * factorial(num - 1)

factorial(5);
//120

O que são "Functors"

É um objeto que implementa o método map. O método map do functor retorna seu próprio conteúdo e, para cada um deles, processa a transformação passada como callback para o método map e retorna um novo functor, que contém a estrutura do primeiro functor, porém, com seu conteúdo transformado.

  1. Adicionando um valor a todos os elementos em um array
const plus1 = num => num + 1;

let numbers = [1, 2, 3];
numbers.map(plus1);
// [2, 3, 4]

Compondo funções

A composição de duas ou mais funções retornando uma nova função.

  1. Combinando duas funções para gerar uma nova
const compose = (f,g) => x => f(g(x));

const toUpperCase = x => x.toUpperCase();
const exclaim = x => `${x}!`;

const angry = compose(exclaim, toUpperCase);

angry("stop this");
// STOP THIS!
  1. Combinando três funções para gerar uma nova
const compose = (f,g) => x => f(g(x));

const toUpperCase = x => x.toUpperCase();
const exclaim = x => `${x}!`;
const moreExclaim = x => `${x}!!!!!`;

const reallyAngry = compose(exclaim, compose(toUpperCase, moreExclaim));

reallyAngry("stop this");
// STOP THIS!!!!!!

Usando desestruturação de parâmetros

Extrair dados de arrays ou objetos usando uma sintaxe que espelha a estrutura literal do array ou objeto. Conhecida também como "Pattern Matching" (em português, algo como, correspondendo ao mesmo padrão).

  1. Selecionando a partir de um padrão
const foo = () => [1, 2, 3];

const [a, b] = foo();
console.log(a, b);
// 1 2
  1. Acumula os valores de restantes
const [a, ...b] = [1, 2, 3];
console.log(a, b);
// 1 [2, 3]
  1. Parâmetros opcionais
const ajax = ({ url = "localhost", port: p = 80}, ...data)  =>
    console.log("Url:", url, "Port:", p, "Rest:", data);

ajax({ url: "someHost" }, "additional", "data", "hello");
// Url: someHost Port: 80 Rest: [ 'additional', 'data', 'hello' ]

ajax({ }, "additional", "data", "hello");
// Url: localhost Port: 80 Rest: [ 'additional', 'data', 'hello' ]

O que é "Currying"

Recebe uma função que recebe múltiplos argumentos e transforma isso em um encadeamento de funções, passando um argumento de cada vez e retornando a próxima função, até que a última retorne o resultado.

  1. Utilizando currying em um objeto
const student = name => grade => `Name: ${name} | Grade: ${grade}`;

student("Matt")(8);
// Name: Matt | Grade: 8
  1. Utilizando currying em uma função de soma
const add = x => y => x + y;

const increment = add(1);
const addFive = add(5);

increment(3);
//4

addFive(10);
// 15

Artigos relacionados

OBS: Todos em inglês.

https://gist.github.com/mikaelbr/9900818

https://www.gitbook.com/book/jcouyang/functional-javascript/details

https://www.youtube.com/playlist?list=PL0zVEGEvSaeEd9hlmCXrk5yUyqUag-n84

http://functionaljavascript.blogspot.com.br/2013/07/functors.html

http://nicoespeon.com/en/2015/01/pure-functions-javascript/

https://drboolean.gitbooks.io/mostly-adequate-guide/

https://www.youtube.com/watch?v=DisD9ftUyCk