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

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

19aa494f35ee3eeb20eed97327a6c186?s=128

Rogério Chaves

May 04, 2016
Tweet

Transcript

  1. 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. 3.

    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. 4.
  4. 5.

    Premissa: com menos features, nós podemos ter um código mais

    funcional e (discutivelmente) mais simples 5
  5. 6.

    MUTABILIDADE É UMA FEATURE 6 x = x + 1

    x - x = 1 0 = 1 n o n s e n s e !
  6. 7.

    NÃO USE MUTABILIDADE 7 Não use Use var const let

    no-var + no-let* + no-mutation* *usando eslint-plugin-immutable ESLint
  7. 8.

    EXEMPLOS 8 let myValues = [ 1, 2, 3 ];

    myValues.push(4); return myValues; const myValues = [ 1, 2, 3 ]; return [ ...myValues, 4];
  8. 9.

    9 let foo = { name: 'Foo' }; foo.age =

    32; return foo; const foo = { name: 'Foo' }; return { ...foo, age: 32 }; EXEMPLOS
  9. 11.

    11 addItemsToCart(); savePurchase(); updateScreen(); const updatedCart = addItems(cart, items); const

    purchase = savePurchase(updatedCart); return view(purchase); EXEMPLOS
  10. 13.

    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', {});
  11. 14.

    CAN’T TOUCH THIS 14 this params () => {} .bind(this)

    *no-this *usando eslint-plugin-immutable ESLint doesn’t create this! Não use Use
  12. 15.

    EXEMPLOS 15 function distance () { return Math.abs(this.x - this.y);

    } const distance = (x, y) => Math.abs(x - y);
  13. 17.

    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
  14. 18.

    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);
  15. 19.

    EXEMPLOS 19 let total = 0; items.forEach((item) => { total

    += item.price; }); return total; return items.reduce((total, item) => total + item.price , 0);
  16. 20.

    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}]
  17. 21.

    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)));
  18. 22.

    NÃO USE IF SEM ELSE 22 just if if/else if/return

    ternary none :( ESLint Não use Use
  19. 23.

    23 if (foo) { return 'bar'; } if (foo) {

    return 'bar'; } return 'baz'; if (foo) { return 'bar'; } else { return 'baz'; } foo ? 'bar' : 'baz'; EXEMPLOS
  20. 25.

    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
  21. 26.

    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
  22. 29.

    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
  23. 30.

    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
  24. 31.

    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