Less Frustration, More Readable Code: Functional Programming in JavaScript with RamdaJS

Less Frustration, More Readable Code: Functional Programming in JavaScript with RamdaJS

A presentation by Nate Taylor at Syntax Conference (SyntaxCon) 2018, in Charleston, South Carolina

C3242e8c2ab4bd8922b125ae5589e443?s=128

Syntax Conference

June 08, 2018
Tweet

Transcript

  1. NATE TAYLOR Developer | Conference Speaker Less Frustration, More Readable

    Code: Functional Programming with RamdaJS
  2. © 2017 NATE TAYLOR @taylonr taylonr.com let candyBars = [milkyWay,

    hersheys, snickers]; let regularSize = []; candyBars.forEach(function(c){ c.versions.forEach(function(v) { if(v.size === 'regular’){ regularSize.push({name: c.name, versions: [v]}); } }); }); Have You Seen This Code?
  3. RamdaJS © 2017 NATE TAYLOR @taylonr taylonr.com

  4. A practical functional library for JavaScript programmers. © 2017 NATE

    TAYLOR @taylonr taylonr.com What is Ramda?
  5. Overarching Goals © 2017 NATE TAYLOR @taylonr taylonr.com Immutable

  6. An object whose state cannot change after being created ©

    2017 NATE TAYLOR @taylonr taylonr.com Immutable
  7. C a n d y b a r s !

    © 2017 NATE TAYLOR @taylonr taylonr.com
  8. © 2017 NATE TAYLOR @taylonr taylonr.com Don’t Lick My Candy

    Bar The Big Idea
  9. Overarching Goals © 2017 NATE TAYLOR @taylonr taylonr.com Immutable Currying

  10. The process of transforming a function that takes multiple arguments

    into a function that takes just a single argument and returns another function if any arguments are still needed. © 2017 NATE TAYLOR @taylonr taylonr.com Currying
  11. C a n d y b a r s !

    © 2017 NATE TAYLOR @taylonr taylonr.com
  12. © 2017 NATE TAYLOR @taylonr taylonr.com contains('peanuts’, candy) containsPeanuts =

    contains('peanuts'); containsPeanuts(candy); Currying
  13. © 2017 NATE TAYLOR @taylonr taylonr.com Define Once, Use Everywhere

    The Big Idea
  14. Overarching Goals © 2017 NATE TAYLOR @taylonr taylonr.com Immutable Currying

    Composition
  15. The act of pipelining the result of one function, to

    the input of another, creating an entirely new function. © 2017 NATE TAYLOR @taylonr taylonr.com Function Composition
  16. C a n d y b a r s !

    © 2017 NATE TAYLOR @taylonr taylonr.com
  17. © 2017 NATE TAYLOR @taylonr taylonr.com const getMultipiecePeanutCandy = (candy)

    => { const multiPiece = eliminateSinglePieces(candy); return eliminateNonPeanuts(multiPiece); } Function Composition
  18. © 2017 NATE TAYLOR @taylonr taylonr.com const getMultipieceCandy = (candy)

    => eliminatePeanuts(eliminateSinglePieces(candy)); Function Composition
  19. © 2017 NATE TAYLOR @taylonr taylonr.com Increase Readability The Big

    Idea
  20. S a m p l e R a m d

    a F u n c t i o n s © 2017 NATE TAYLOR @taylonr taylonr.com
  21. Using Multiple Functions © 2017 NATE TAYLOR @taylonr taylonr.com const

    arr = ['Milky Way', 'Twix', 'Snickers’, ‘3 Musketeers', 'm&ms']; const containsCandy = (candy) => { contains(candy, take(2, sortBy(toLower, arr))); } containsCandy('Milky Way'); //false
  22. Using Multiple Functions © 2017 NATE TAYLOR @taylonr taylonr.com const

    arr = ['Milky Way', 'Twix', 'Snickers’, ‘3 Musketeers', 'm&ms']; const containsCandy = (candy) => { contains(candy, take(2, sortBy(toLower, arr))); } containsCandy('Milky Way'); //false
  23. Pipe © 2017 NATE TAYLOR @taylonr taylonr.com const containsCandy =

    (candy) => { let arr = ['Milky Way', 'Twix', 'Snickers’, '3 Musketeers', 'm&ms']; return pipe( sortBy(toLower), take(2), contains(candy) )(arr) } containsCandy('Milky Way'); //false
  24. List Functions © 2017 NATE TAYLOR @taylonr taylonr.com

  25. all | any | none © 2017 NATE TAYLOR @taylonr

    taylonr.com R.all(_ => _ % 2 == 0, [1, 2, 3, 4]) //false R.any(_ => _ % 2 == 0, [1, 2, 3, 4]) //true R.none(_ => _ % 2 == 0, [1, 2, 3, 4]) //false
  26. zip © 2017 NATE TAYLOR @taylonr taylonr.com zip([1, 2, 3],

    ['a', 'b', 'c']); //=> [[1, 'a'], [2, 'b'], [3, 'c']]
  27. Combining Together © 2017 NATE TAYLOR @taylonr taylonr.com var csvHeaders

    = ['accountName', 'assetName', 'quantity’]; var firstRow = ['accountName', 'assetName', 'quantity']; var createObj = x => {return {csv: x[0], val: x[1]};}; var csvMatchesValue = x => x.csv === x.val; var isHeader = R.pipe( R.zip(csvHeaders), R.map(createObj), R.all(csvMatchesValue) ); isHeader(firstRow)
  28. Object Functions © 2017 NATE TAYLOR @taylonr taylonr.com

  29. path | pathOr © 2017 NATE TAYLOR @taylonr taylonr.com let

    milkyWay = { name: 'Milky Way’, nutrition: { fat: 10 } }; R.path(['nutrition', 'fat’]); //10 R.path(['nutrition', 'sodium’]); //undefined R.pathOr('0%', ['nutrition', 'vitamins', 'A’]); //0%
  30. pick © 2017 NATE TAYLOR @taylonr taylonr.com let milkyWay =

    { name: 'Milky Way', calories: 210, funSize: false, nutrition: { fat: 10, carbohydrate: 41, protein: 2.3 } }; R.pick(['name', 'calories'], milkyWay); //{name: 'Milky Way', calories: 210}
  31. Other Categories © 2017 NATE TAYLOR @taylonr taylonr.com Logic Math

    String Relation
  32. Why Use Ramda? © 2017 NATE TAYLOR @taylonr taylonr.com

  33. Any fool can write code that a computer can understand.

    Good programmers write code that humans can understand. © 2017 NATE TAYLOR @taylonr taylonr.com -- Martin Fowler
  34. © 2017 NATE TAYLOR @taylonr taylonr.com var buyACandyBar = (me,

    cashier) => { pipe( driveToStore(), findAllCandyBars(), eliminateKingSize(), eliminatePeanuts(), takeOne(), pay(cashier) )(me); }; Readable Code
  35. How Do I Get Started? © 2017 NATE TAYLOR @taylonr

    taylonr.com Start With Lists Eliminate For Loops Think Small Think Transformation
  36. NATE TAYLOR @taylonr| taylonr@gmail.com THANK YOU