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

Functional Programming with Ramda

Ryan Aghdam
September 23, 2016

Functional Programming with Ramda

Discusses basics of functional programming concepts, how to use Ramda, and applying these principles to React.

Ryan Aghdam

September 23, 2016
Tweet

Other Decks in Programming

Transcript

  1. Agenda • What is functional programming? • Why functional programming?

    • How to do functional programming? • Functional programming & React
  2. What? Style/Philosophy • Based on Church-Turing thesis (1930’s) • Collection

    of concepts: • First-class functions • Pure functions • Composition • Higher-order functions
  3. What? First-class functions var mathFunctions = [ isEven, isOdd, isPrime,

    ]; • Functions are treated like any other value • Can be referenced by name
  4. What? First-class functions map(isEven, [1, 2, 3, 4]); • Functions

    are treated like any other value • Passed as argument
  5. What? First-class functions function negate(f) { return function (x) {

    return !f(x); }; } var isOdd = negate(isEven); • Functions are treated like any other value • Returned as value
  6. What? Pure functions • Given same input, will always return

    same output • No side-effects • Resilient to outside factors • Use Redux (or similar) to manage state
  7. What? Composition “Composition feels like function husbandry. You, breeder of

    functions, select two with traits you’d like to combine and mash them together to spawn a brand new one.” Professor Frisby’s Mostly Adequate Guide to Functional Programming function compose(f, g) { return function (x) { return f(g(x)); }; }
  8. What? Composition const Blue = children => ( <div style="color:#000cde;">

    {children} </div> ); const Big = children => ( <div style="font-size:4rem;"> {children} </div> ); const Logo = compose(Big, Blue); Logo("PayPal") <div style="font-size:4rem;"> <div style="color:#000cde;"> PayPal </div> </div>
  9. What? Higher-order function function map(f, list) { var acc =

    []; for (var i = 0; i < list.length; i++) { acc.push(f(list[i])); } return acc; } function negate(f) { return function (x) { return !f(x); }; } Functions that accept a function as an argument or return a function
  10. Why? Testability • Pure functions are easy to test •

    Don’t need to account for side-effects when testing • Achieve full test coverage (unit & integration) • Declarative style reduces branches/permutations
  11. How? Filter var cars = [ { year: 1964.5, make:

    'Ford', model: 'Mustang', origin: 'US', }, { year: 1963, make: 'Aston Martin', model: 'DB5', origin: 'UK', }, { year: 2013, make: 'Scion', model: 'FR-S', origin: 'JP', }, { year: 1991, make: 'Mazda', model: 'Miata', origin: 'JP', }, ];
  12. How? Filter function getJapaneseCars(cars) { var acc = []; for

    (var i = 0; i < cars.length; i++) { if (cars[i].origin === 'JP') { acc.push(cars[i]); } } return acc; }
  13. How? Filter w/ Lodash var _ = require('lodash'); function getJapaneseCars(cars)

    { return _.filter(cars, function (car) { return car.origin === 'JP'; }); }
  14. How? Filter w/ Ramda import { filter, propEq } from

    'ramda'; const getJapanese = filter(propEq('origin', 'JP'));
  15. How? Filter w/ Ramda import { filter, propEq } from

    'ramda'; const getJapanese = filter(propEq('origin', 'JP')); const cars = [ { year: 1964.5, make: 'Ford', model: 'Mustang', origin: 'US' }, { year: 1963, make: 'Aston Martin', model: 'DB5', origin: 'US' }, { year: 2013, make: 'Scion', model: 'FR-S', origin: 'JP' }, { year: 1991, make: 'Mazda', model: 'Miata', origin: 'JP' }, ]; getJapanese(cars); => [ { year: 2013, make: 'Scion', model: 'FR-S', origin: 'JP' }, { year: 1991, make: 'Mazda', model: 'Miata', origin: 'JP' }, ]
  16. How? Filter w/ Ramda import { filter, propEq } from

    'ramda'; const getJapanese = filter(propEq('origin', 'JP')); const pencils = [ { make: 'Mirado', model: 'Black Warrior', origin: 'US' }, { make: 'Tombow', model: '8900', origin: 'JP' }, { make: 'Eberhard Faber', model: 'Mongol 482', origin: 'US' }, { make: 'Palomino', model: 'Blackwing', origin: 'JP' }, ]; getJapanese(pencils); => [ { make: 'Tombow', model: '8900', origin: 'JP' }, { make: 'Palomino', model: 'Blackwing', origin: 'JP' }, ]
  17. With React? • Popular React is not functional • Large

    classes • Long, complex render() methods • Used like a tempting engine • An example component: • 568 lines • onSubmit() and submitForm(); ~100 lines, ~20 if/else • ~50 lines of markup • Dozens of helpers that mutate variables
  18. With React? Declarative const List = children => <ul>{children}</ul>; const

    Task = ({ id, text, isDone }) => ( <li key={id}> <Checkbox checked={isDone} /> <span>{text}</span> </li> ); const Checkbox = ({ checked }) => ( <input type="checkbox" checked={checked} /> ); const TodoList = R.compose(List, R.map(Task)); TodoList([{ id: 1, text: “slides”, isDone: false}]);
  19. Summary • Functional programming concepts • First-class functions • Pure

    functions • Composition • Higher-order functions • Benefits: • Readability • Testability • How • Not Lodash • Ramda
  20. Further Reading • Why Ramda? • Professor Frisby’s Mostly Adequate

    Guide to Functional Programming • Thinking in Ramda