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

Faça programação funcional com JavaScript codando menos

Faça programação funcional com JavaScript codando menos

Rogério Chaves

May 04, 2016
Tweet

More Decks by Rogério Chaves

Other Decks in Programming

Transcript

  1. FAÇA PROGRAMAÇÃO FUNCIONAL COM JAVASCRIPT CODANDO MENOS o que não

    fazer para alcançar um código mais simples e funcional
  2. os exemplos serão mostrados em JS, mas eles podem ser

    adaptados pra praticamente qualquer linguagem de programação que possa passar funções ou lambdas como argumentos 3
  3. Premissa: com menos features, nós podemos ter um código mais

    funcional e (discutivelmente) mais simples 5
  4. MUTABILIDADE É UMA FEATURE 6 x = x + 1

    x - x = 1 0 = 1 n o n s e n s e !
  5. NÃO USE MUTABILIDADE 7 Não use Use var const let

    no-var + no-let* + no-mutation* *usando eslint-plugin-immutable ESLint
  6. EXEMPLOS 8 let myValues = [ 1, 2, 3 ];

    myValues.push(4); return myValues; const myValues = [ 1, 2, 3 ]; return [ ...myValues, 4];
  7. 9 let foo = { name: 'Foo' }; foo.age =

    32; return foo; const foo = { name: 'Foo' }; return { ...foo, age: 32 }; EXEMPLOS
  8. 11 addItemsToCart(); savePurchase(); updateScreen(); const updatedCart = addItems(cart, items); const

    purchase = savePurchase(updatedCart); return view(purchase); EXEMPLOS
  9. EXEMPLOS 13 array.push(5); object.key = 'five'; myObj.setFoo('bar'); i++; post('http://url', {});

    return [ ...array, 5 ]; return { ...object, key: 5 }; return new MyObj('bar'); return i + 1; return post('http://url', {});
  10. CAN’T TOUCH THIS 14 this params () => {} .bind(this)

    *no-this *usando eslint-plugin-immutable ESLint doesn’t create this! Não use Use
  11. EXEMPLOS 15 function distance () { return Math.abs(this.x - this.y);

    } const distance = (x, y) => Math.abs(x - y);
  12. NÃO USE FOR/EACH 17 for reduce map .forEach filter no-for-loops*

    + no-implicit-side-effects** *usando bahmutov/eslint-rules ESLint **usando eslint-plugin-no-implicit-side-effects Não use Use
  13. EXEMPLOS 18 let uppercaseNames = []; for (let i =

    0; i < names.length; i++) { let uppercaseName = toUpperCase(names[i]); uppercaseNames.push(uppercaseName); } return uppercaseNames; return names.map(toUppercase);
  14. EXEMPLOS 19 let total = 0; items.forEach((item) => { total

    += item.price; }); return total; return items.reduce((total, item) => total + item.price , 0);
  15. EXEMPLOS 20 let names = []; let result = [];

    list.forEach((item) => { const uppercasedName = toUpperCase(item.name); if (names.indexOf(uppercasedName) < 0) { names.push(uppercasedName); result.push({ name: uppercasedName, count: 1 }); } else { result[names.indexOf(uppercasedName)].count++; } }); return result; // input: [{name: ‘foo'}, {name: 'foo'}, {name: 'foo'}, {name: 'bar'}, {name: 'bar'}, {name: 'baz'}] // output: [{name: 'FOO', count: 3}, {name: 'BAR', count: 2}, {name: 'BAZ', count: 1}]
  16. EXEMPLOS 21 const mapToUpperCase = list => list.map(item => ({

    ...item, name: toUpperCase(item.name) })); const countRepeated = (list, value) => list.reduce((total, item) => item.name === value.name ? total + 1 : total, 0); const addRepeatCount = list => list.map(item => ({ ...item, count: countRepeated(list, item) })); const removeDuplicates = list => list.filter((item, index) => list.indexOf(list.find(x => x.name === item.name)) === index); return removeDuplicates(addRepeatCount(mapToUpperCase(list)));
  17. NÃO USE IF SEM ELSE 22 just if if/else if/return

    ternary none :( ESLint Não use Use
  18. 23 if (foo) { return 'bar'; } if (foo) {

    return 'bar'; } return 'baz'; if (foo) { return 'bar'; } else { return 'baz'; } foo ? 'bar' : 'baz'; EXEMPLOS
  19. 25 class Person { getFormattedName (person) { return person.name.toUpperCase(); }

    save (person) { return post('http://saveName', { name: person.name }); } } const getFormattedName = (person) => person.name.toUpperCase(); const save = (person) => post('http://saveName', { name: person.name }); EXEMPLOS
  20. 26 class ListComponent extends React.Component { render () { return

    <ul>{ this.listItems() }</ul>; } listItems () { return this.props.items.map(item => <li>{ item.name }</li>); } } const listComponent = (props) => <ul>{ listItems(props.items) }</ul>; const listItems = (items) => items.map(item => <li>{ item.name }</li>); EXEMPLOS
  21. NO OPTIONAL ARGS (BONUS) 29 optional args for changing behaviour

    specialized functions none :( ESLint function composition currying default args for common scenarios Não use Use
  22. 30 const getPrices = (items, onlyOdds = true) => {

    const prices = items.map(item => item.price); if (onlyOdds) { return prices.filter(price => price % 2 !== 0); } return items; }; const getPrices = items => items.map(item => item.price); const getOddPrices = items => getPrices(items).filter(price => price % 2 !== 0); EXEMPLOS
  23. 31 const increasePrices = (items, by = 5) => items.map(item

    => ({ ...item, price: item.price + by })); increasePrices(list1); increasePrices(list2); increasePrices(list3, 10); const increasePrices = amount => items => items.map(item => ({ ...item, price: item.price + amount })); const increasePricesBy5 = increasePrices(5); const increasePricesBy10 = increasePrices(10); increasePricesBy5(list1); increasePricesBy5(list2); increasePricesBy10(list3); EXEMPLOS