Slide 1

Slide 1 text

Marcel Gonçalves dos Santos @marcelgsantos programação funcional na prática c o Ramda JavaScript em

Slide 2

Slide 2 text

pensandonaweb.com.br desenvolvedor web full-stack Marcel Gonçalves dos Santos @marcelgsantos

Slide 3

Slide 3 text

@phpsp phpsp.org.br

Slide 4

Slide 4 text

Interaja nas mídias sociais! 
 
 - fale sobre o evento, palestrantes e conteúdo - tire fotos do evento e publique 
 - interaja com outros participantes do evento - tire dúvidas ou dê feedbacks para os palestrantes

Slide 5

Slide 5 text

O que é programação funcional?

Slide 6

Slide 6 text

é um paradigma de programação que utiliza funções puras e foca na transformação do estado

Slide 7

Slide 7 text

O que é paradigma de programação?

Slide 8

Slide 8 text

são modelos ou estilos de programação suportados por linguagens que agrupam certas características comuns

Slide 9

Slide 9 text

os p ar adigmas de pro gr amação definem c om o os códigos são es tr ut ur ados…

Slide 10

Slide 10 text

principais paradigmas de programação 
 os dois principais paradigmas são o imperativo e o declarativo

Slide 11

Slide 11 text

paradigma imperativo 
 descreve a resolução de um problema através de comandos que o computador pode compreender e executar

Slide 12

Slide 12 text

paradigma imperativo 
 os paradigmas procedural e orientado a objetos são exemplos de paradigmas imperativos

Slide 13

Slide 13 text

let result = 0; / / Imperative code to sum 1 to 10 for (let i = 0; i < = 10; i + + ) { result += i; } console.log(result); / / 55

Slide 14

Slide 14 text

paradigma declarativo 
 permite especi fi car o que deve ser computado e não como deve ser computado

Slide 15

Slide 15 text

paradigma declarativo 
 os paradigmas funcional e lógico são exemplos de paradigmas declarativos

Slide 16

Slide 16 text

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; / / Declarative code to sum 1 to 10 const sum = (a, b) = > a + b; const result = numbers.reduce(sum); console.log(result);

Slide 17

Slide 17 text

paradigmas de algumas linguagens de programação 
 
 imperativo 
 procedural - C e Pascal orientado a objetos - C++, Java, PHP, Python e Ruby 
 
 declarativo 
 lógico - Prolog funcional - Clojure, Elixir, Elm, Erlang, F#, Haskell, Lisp, OCaml e Scala

Slide 18

Slide 18 text

Programação Funcional λ

Slide 19

Slide 19 text

paradigma de programação que utiliza funções puras e foca na transformação do estado

Slide 20

Slide 20 text

baseado no cálculo lambda proposto por Alonzo Church na década de 30

Slide 21

Slide 21 text

na programação funcional as funções são tratadas como conceito principal

Slide 22

Slide 22 text

Uma função matemática tr ata-se de um simples mapeamento en tr e o d om ínio e o c on tr a-d om ínio. 1 2 3 D B A C X Y

Slide 23

Slide 23 text

JavaScript λ

Slide 24

Slide 24 text

presente em todos os lugares como navegadores, servidores, mobile, desktop e dispositivos IoT

Slide 25

Slide 25 text

muito popular e utilizada

Slide 26

Slide 26 text

todos os programadores deveriam aprender

Slide 27

Slide 27 text

possui suporte para diversas funcionalidades de programação funcional

Slide 28

Slide 28 text

Estado λ

Slide 29

Slide 29 text

o estado de um programa é representado pelos valores dos dados armazenados na memória em qualquer ponto de execução do programa

Slide 30

Slide 30 text

o estado de uma aplicação é alterado a cada interação feita pelo usuário…

Slide 31

Slide 31 text

…ou pelo próprio sistema e pode ser representado por uma estrutura de dados

Slide 32

Slide 32 text

a maioria dos bugs são relacionados ao controle de estado

Slide 33

Slide 33 text

Funções Puras λ

Slide 34

Slide 34 text

1. ter parâmetros de entrada 
 2. não depender do estado externo 
 3. retorno baseado nos valores de entrada 
 4. não devem causar efeitos colaterais funções puras

Slide 35

Slide 35 text

/ / pure or impure function? let counter = 0; function increment() { counter + + ; return counter; } console.log(increment()); / / 1

Slide 36

Slide 36 text

/ / pure function (ES5 syntax) function add(x, y) { return x + y; } console.log(add(2, 3)); / / 5

Slide 37

Slide 37 text

/ / pure function (ES6 syntax) const add = (x, y) = > x + y; console.log(add(2, 3)); / / 5

Slide 38

Slide 38 text

por que utilizar funções puras? 
 são reutilizáveis, componíveis, fáceis de testar, fáceis de cachear e paralelizáveis

Slide 39

Slide 39 text

transparência referencial 
 propriedade que garante que a saída de uma função pura sempre será a mesma dado um mesmo conjunto de argumentos

Slide 40

Slide 40 text

/ / referential transparency const add = (x, y) = > x + y; console.log(add(2, 3) = = = 5); / / true console.log(5 = = = 5); / / true

Slide 41

Slide 41 text

pode não ser fácil criar funções puras

Slide 42

Slide 42 text

porém, a restritividade ajuda a melhorar o foco

Slide 43

Slide 43 text

Mais sobre Funções λ

Slide 44

Slide 44 text

funções de alta ordem e 
 funções de primeira classe 
 são funções que podem ser atribuídas a variáveis, passadas como argumentos e retornadas de uma função

Slide 45

Slide 45 text

/ / high - order function const add = (x, y) = > x + y; const numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce(add); const sum10 = numbers.reduce(add, 10); console.log(sum); / / 15 console.log(sum10); / / 25

Slide 46

Slide 46 text

funções anônimas 
 funções que não possuem nome e que, geralmente, são passadas como argumento ou atribuídas

Slide 47

Slide 47 text

/ / anonymous function const numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce((x, y) = > x + y); console.log(sum); / / 15

Slide 48

Slide 48 text

closures 
 funções que possuem acesso à valores do escopo externo

Slide 49

Slide 49 text

/ / closure function function greet(greeting) { return function (name) { return `${greeting} ${name}!`; }; } const greet2 = greeting = > name = > `${greeting} ${name}!`; console.log(greet('Hello')('Mary')); / / Hello Mary! console.log(greet2('Hello')('John')); / / Hello John!

Slide 50

Slide 50 text

recursão 
 é quando uma função é definida em termos de si própria, ou seja, quando a função chama ela mesma

Slide 51

Slide 51 text

diferença entre função e procedimento (procedure) 
 uma função recebe um valor e retorna um resultado; um procedimento é um conjunto de comandos executados numa ordem

Slide 52

Slide 52 text

“D on 't think of functi on s as a c ol lecti on of ins tr ucti on s. Think of them as n on -des tr uctive op er ati on s on input `d ou ble = n => n * 2;`” Eric Ellio tt , 2016. https:/ /twitter.com/_ericelliott/status/685172918784004097

Slide 53

Slide 53 text

memoize 
 técnica que permite que funções custosas sejam cacheadas para execuções posteriores mais rápidas

Slide 54

Slide 54 text

Imutabilidade λ

Slide 55

Slide 55 text

a imutabilidade diz que um dado não pode ser alterado após a sua criação

Slide 56

Slide 56 text

a imutabilidade permite maior con fi ança e evita que erros ocorram

Slide 57

Slide 57 text

o JavaScript não possui suporte a dados imutáveis de forma nativa

Slide 58

Slide 58 text

porém, pode-se trabalhar com dados imutáveis em JavaScript utilizando algumas técnicas

Slide 59

Slide 59 text

Currying e aplicação parcial λ

Slide 60

Slide 60 text

o currying é a técnica que permite transformar uma função que recebe múltiplos argumentos em uma função que…

Slide 61

Slide 61 text

…recebe apenas um argumento e que retorna uma função que aceita os argumentos restantes

Slide 62

Slide 62 text

a aplicação parcial é quando se executa uma função e passa apenas parte de seus argumentos

Slide 63

Slide 63 text

a aplicação parcial permite fazer a especialização de uma função mais genérica

Slide 64

Slide 64 text

/ / specialization from a curried function / / using partial application const greet = R.curry((greeting, name) = > `${greeting} ${name}`); const greetMorning = greet('Good Morning'); console.log(greetMorning('Alice')); / / Good Morning Alice

Slide 65

Slide 65 text

currying e aplicação parcial são recursos muito utilizados em programação funcional

Slide 66

Slide 66 text

na programação funcional deve-se levar em consideração a ordem dos parâmetros

Slide 67

Slide 67 text

os parâmetros mais genéricos devem vir mais para o início e os parâmetros mais especí fi cos devem vir mais para o fi nal

Slide 68

Slide 68 text

o JavaScript não possui suporte nativo para currying como nas linguagens puramente funcionais Elm ou Haskell

Slide 69

Slide 69 text

Composição de Funções λ

Slide 70

Slide 70 text

a composição é o processo de combinar uma ou mais funções para criar uma nova função

Slide 71

Slide 71 text

/ / composing some functions to achieve a new behaviour const sentence = 'estava à toa na vida o meu amor me chamou pra ver a banda passar cantando coisas de amor'; const wordCount = R.length(R.split(' ', sentence)); console.log(wordCount); / / 19

Slide 72

Slide 72 text

é uma solução elegante e legível e ajuda a evitar a utilização do aninhamento de funções

Slide 73

Slide 73 text

o Ramda possui uma função que permite criar uma nova função a partir da composição de funções

Slide 74

Slide 74 text

/ / create a function using composition const sentence = 'estava à toa na vida o meu amor me chamou pra ver a banda passar cantando coisas de amor'; const countWords = R.compose(R.length, R.split); console.log(countWords(' ', sentence)); / / 19

Slide 75

Slide 75 text

Biblioteca 
 Ramda λ

Slide 76

Slide 76 text

uma biblioteca construída para o estilo de programação funcional que facilita a utilização de pipelines e dados imutáveis

Slide 77

Slide 77 text

possui foco no estilo puramente funcional

Slide 78

Slide 78 text

todas as funções do Ramda são auto-curried

Slide 79

Slide 79 text

os argumentos das funções do Ramda são organizados de forma a facilitar a utilização de currying

Slide 80

Slide 80 text

Caso de Uso 1 somar os preços dos produtos de um carrinho de compras

Slide 81

Slide 81 text

/ / shopping cart const cart = [ {id: 1, product: 'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; / / get prices from shopping cart and sum them 
 / / using intermediate values const cartPrices = R.map(item = > item.price, cart); const cartSum = R.sum(cartPrices); console.log(cartSum); / / 1877 realiza o mapeamento da lista de produtos (objetos) para uma lista de preços (números) faz a somatória da lista de números e retorna o total Passo 1

Slide 82

Slide 82 text

/ / shopping cart const cart = [ {id: 1, product: 'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; / / get prices from shopping cart and sum them 
 / / using function composition const totalCart = R.compose( R.sum, R.map(item = > item.price), ); console.log(totalCart(cart)); / / 1877 cria uma nova função a partir da composição de funções e elimina valores intermediários Passo 2 aplicação parcial da função map a composição é feita da direita para a esquerda

Slide 83

Slide 83 text

/ / shopping cart const cart = [ {id: 1, product: 'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; / / get prices from shopping cart and sum them / / using function composition with pipe const totalCart = R.pipe( R.map(item = > item.price), R.sum, ); console.log(totalCart(cart)); / / 1877 Passo 3 o pipe de funções é feito da esquerda para a direita e facilita a leitura do código

Slide 84

Slide 84 text

Caso de Uso 2 limpar dados vindo de um formulário e realizar um cálculo

Slide 85

Slide 85 text

/ / cleaning data from an input const price = '100'; const discount = (perc, value) = > perc * value; let priceInt = parseInt(price); let priceDiscount = discount(0.2, priceInt); console.log(priceDiscount); / / 20 Passo 1

Slide 86

Slide 86 text

/ / cleaning data from an input const price = '100'; const discount = (perc, value) = > perc * value; / / using partial application const discount20 = R.partial(discount, [0.2]); let priceInt = parseInt(price); let priceDiscount = discount20(priceInt); console.log(priceDiscount); / / 20 Passo 2 cria uma nova função a partir da aplicação parcial de uma existente

Slide 87

Slide 87 text

/ / cleaning data from an input const price = '100'; const discount = (perc, value) = > perc * value; / / using function composition const priceDiscount = R.pipe( parseInt, R.partial(discount, [0.2]), ); console.log(priceDiscount(price)); / / 20 Passo 3 cria uma nova função a partir da composição de funções utilizando a função pipe e elimina valores intermediários

Slide 88

Slide 88 text

/ / cleaning data from an input const price = 'lambda!'; const discount = (perc, value) = > perc * value; / / using function composition const priceDiscount = R.pipe( parseInt, R.partial(discount, [0.2]), ); console.log(priceDiscount(price)); / / null Passo 4 erro ao receber um valor não numérico

Slide 89

Slide 89 text

/ / cleaning data from an input const price = 'lambda!'; const discount = (perc, value) = > perc * value; / / using function composition const priceDiscount = R.pipe( parseInt, R.defaultTo(0), R.partial(discount, [0.2]), ); console.log(priceDiscount(price)); / / 0 Passo 5 retorna o valor padrão para o caso de um valor não truthy

Slide 90

Slide 90 text

Outras Bibliotecas λ

Slide 91

Slide 91 text

1. RxJS 
 2. Lodash 
 3. Immutable.js 
 4. HyperApp outras bibliotecas

Slide 92

Slide 92 text

Conclusão

Slide 93

Slide 93 text

a programação funcional não é sobre não ter estado…

Slide 94

Slide 94 text

…e sim sobre eliminar estado e efeito colateral sempre que possível e controlar efeitos colaterais quando necessário

Slide 95

Slide 95 text

existem inúmeros conceitos relacionados a programação funcional como functors, mônades, lazy evaluation, lens, tail call optimization…

Slide 96

Slide 96 text

vá em frente e divirta-se!

Slide 97

Slide 97 text

Referências

Slide 98

Slide 98 text

1. Mostly Adequate Guide 
 2. Functional-Light JavaScript 
 3. Ramda Docs 
 4. JavaScript Funcional - Arthur Xavier referências

Slide 99

Slide 99 text

Avalie!

Slide 100

Slide 100 text

@marcelgsantos speakerdeck.com/marcelgsantos Obrigado. Perguntas?