O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
Globalcode – Open4education
Ramda
Derek Stavis
Software Engineer
Globalcode – Open4education
Who?
Derek Stavis
github.com/derekstavis
Software Engineer
Ruby, JavaScript, Python, C
Node, R...
Globalcode – Open4education
Have you been using functional
helper libraries?
Globalcode – Open4education
Underscore?
🤔
Globalcode – Open4education
Lodash?
🤔
Globalcode – Open4education
Really?
🙄
Globalcode – Open4education
Those are really good libraries
Globalcode – Open4education
Weren't designed with a functional
mindset from day 0
Globalcode – Open4education
Ramda
A functional programming library
http://ramdajs.com
Globalcode – Open4education
Meet Ramda
Emphasizes a purer functional style
Immutability and side-effect free functions
Ram...
Globalcode – Open4education
Small, single-responsibility and
reusable functions
Globalcode – Open4education
Ramda shines on currying
Globalcode – Open4education
Ramda shines on currying
var names = [
{ name: 'Pablo' },
{ name: 'Escobar' },
{ name: 'Gaviri...
Globalcode – Open4education
Ramda shines on currying
var names = [
{ name: 'Pablo' },
{ name: 'Escobar' },
{ name: 'Gaviri...
Globalcode – Open4education
Currying?
😨
Globalcode – Open4education
Currying was named after
Haskell Curry
One of the first to investigate such technique
Globalcode – Open4education
Turn a function that expects
multiple arguments into one that,
when supplied fewer arguments,
...
Globalcode – Open4education
Ramda is about currying
const cookPasta = R.curry((water, heat, pasta) => { ... })
// Have eve...
Globalcode – Open4education
This is truly powerful
Globalcode – Open4education
Ramda is all curried
😎
Globalcode – Open4education
Point-free programming
🖖
Globalcode – Open4education
Ramda is all curried
R.add(2, 3) //=> 5
R.add(7)(10) //=> 17
R.contains(2, [1, 2, 3]) //=> tru...
Globalcode – Open4education
Apply the parameters left-to-right
when you have them
👉
Globalcode – Open4education
But what if you'd like to apply the
leftmost or intermediate arguments
before the rightmost?
Globalcode – Open4education
Leave argument placeholders
✍
Globalcode – Open4education
Functional placeholder
R.minus(R.__, 5)(10) //=> 5
R.divide(R.__, 5)(10) //=> 17
R.contains(R....
Globalcode – Open4education
Or do partial application
Globalcode – Open4education
Ramda does partial application
both left-to-right and right-to-left
Globalcode – Open4education
In fact, there's no currying as in
theoretical math, Ramda currying
is, in reality, partial ap...
Globalcode – Open4education
Partial application
const greet = (salutation, title, name) =>
`${salutation}, ${title} ${name...
Globalcode – Open4education
Ramda also makes available some
cool and very useful functions
Globalcode – Open4education
Avoiding you to rewrite the same
stuff that you always have to
Globalcode – Open4education
Ramda functions are divided into
various categories
Globalcode – Open4education
Ramda functions categories
Function
Math
List
Logic
Object
Relation
Globalcode – Open4education
Function functions
// Always return the same thing, ignoring arguments
const name = R.always('...
Globalcode – Open4education
Math functions
// Addition
R.add(1, 2) //=> 3
// Subtraction
R.subtract(2, 1) //=> 1
// Sum al...
Globalcode – Open4education
List functions
// Check if all elements match a predicate
R.all(R.gt(4), [1, 2, 3]) //=> true
...
Globalcode – Open4education
Logic functions
// Combine predicates into a single function
var gt10 = x => x > 10
var even =...
Globalcode – Open4education
Object functions
// Add a key and value to an already existing object
R.assoc('c', 3, {a: 1, b...
Globalcode – Open4education
Relation functions
// Lots of comparison functions
// Kinda tricky, but also kinda natural
R.g...
Globalcode – Open4education
Ramda works well with Promise
Globalcode – Open4education
Ramda and Promises
app.get('/v1/plants/:id', auth.active, (req, res) => {
db.plants.find({ id:...
Globalcode – Open4education
Ramda and Promises
function timesValues (number) {
return spot(number)
.then(spot =>
db.collec...
Globalcode – Open4education
Thanks for watching
Questions?
github.com/derekstavis
twitter.com/derekstavis
facebook.com/der...
Próximos SlideShares
Carregando em…5
×

TDC2016POA | Trilha Programacao Funcional - Ramda JS como alternativa a underscore e lodash

167 visualizações

Publicada em

Ramda JS como alternativa a underscore e lodash

Publicada em: Educação
  • Seja o primeiro a comentar

TDC2016POA | Trilha Programacao Funcional - Ramda JS como alternativa a underscore e lodash

  1. 1. Globalcode – Open4education Ramda Derek Stavis Software Engineer
  2. 2. Globalcode – Open4education Who? Derek Stavis github.com/derekstavis Software Engineer Ruby, JavaScript, Python, C Node, React & Webpack Advocate
  3. 3. Globalcode – Open4education Have you been using functional helper libraries?
  4. 4. Globalcode – Open4education Underscore? 🤔
  5. 5. Globalcode – Open4education Lodash? 🤔
  6. 6. Globalcode – Open4education Really? 🙄
  7. 7. Globalcode – Open4education Those are really good libraries
  8. 8. Globalcode – Open4education Weren't designed with a functional mindset from day 0
  9. 9. Globalcode – Open4education Ramda A functional programming library http://ramdajs.com
  10. 10. Globalcode – Open4education Meet Ramda Emphasizes a purer functional style Immutability and side-effect free functions Ramda functions are automatically curried Argument ordering convenient to currying Keep rightmost the data to be operated
  11. 11. Globalcode – Open4education Small, single-responsibility and reusable functions
  12. 12. Globalcode – Open4education Ramda shines on currying
  13. 13. Globalcode – Open4education Ramda shines on currying var names = [ { name: 'Pablo' }, { name: 'Escobar' }, { name: 'Gaviria' } ] var getName = R.prop('name') var pickNames = R.map(getName, names) pickNames() => [ 'Pablo', 'Escobar', 'Gaviria' ]
  14. 14. Globalcode – Open4education Ramda shines on currying var names = [ { name: 'Pablo' }, { name: 'Escobar' }, { name: 'Gaviria' } ] var getName = R.prop('name') var pickNames = R.map(getName) pickNames(names) => [ 'Pablo', 'Escobar', 'Gaviria' ]
  15. 15. Globalcode – Open4education Currying? 😨
  16. 16. Globalcode – Open4education Currying was named after Haskell Curry One of the first to investigate such technique
  17. 17. Globalcode – Open4education Turn a function that expects multiple arguments into one that, when supplied fewer arguments, returns a new function that awaits the remaining ones
  18. 18. Globalcode – Open4education Ramda is about currying const cookPasta = R.curry((water, heat, pasta) => { ... }) // Have everything needed cookPasta (water, heat, pasta) // Forgot to buy pasta cookPasta (water, heat)(pasta) // No gas and no pasta cookPasta (water)(heat, pasta) // Had to go twice to supermarket cookPasta (water)(heat)(pasta)
  19. 19. Globalcode – Open4education This is truly powerful
  20. 20. Globalcode – Open4education Ramda is all curried 😎
  21. 21. Globalcode – Open4education Point-free programming 🖖
  22. 22. Globalcode – Open4education Ramda is all curried R.add(2, 3) //=> 5 R.add(7)(10) //=> 17 R.contains(2, [1, 2, 3]) //=> true R.contains(1)([1, 2, 3]) //=> true R.replace(/foo/g, 'bar', 'foo foo') //=> 'bar bar' R.replace(/foo/g, 'bar')('foo foo') //=> 'bar bar' R.replace(/foo/g)('bar')('foo foo') //=> 'bar bar'
  23. 23. Globalcode – Open4education Apply the parameters left-to-right when you have them 👉
  24. 24. Globalcode – Open4education But what if you'd like to apply the leftmost or intermediate arguments before the rightmost?
  25. 25. Globalcode – Open4education Leave argument placeholders ✍
  26. 26. Globalcode – Open4education Functional placeholder R.minus(R.__, 5)(10) //=> 5 R.divide(R.__, 5)(10) //=> 17 R.contains(R.__, [1, 2, 3])(2) //=> true R.contains(R.__, [1, 2, 3])(1) //=> true R.contains(R.__, R.__)(1)([1, 2, 3]) //=> true
  27. 27. Globalcode – Open4education Or do partial application
  28. 28. Globalcode – Open4education Ramda does partial application both left-to-right and right-to-left
  29. 29. Globalcode – Open4education In fact, there's no currying as in theoretical math, Ramda currying is, in reality, partial application
  30. 30. Globalcode – Open4education Partial application const greet = (salutation, title, name) => `${salutation}, ${title} ${name}!` const greetMrCrowley = R.partialRight(greet, ['Mr.', 'Crowley']) greetMrCrowley('Hello') //=> 'Hello, Mr. Crowley!' const greetMr = R.partial(greet, ['Hello', 'Mr.']) const greetMs = R.partial(greet, ['Hello', 'Ms.']) greetMr('Mendel') // => 'Hello, Mr. Mendel' greetMs('Curie') // => 'Hello, Ms. Curie'
  31. 31. Globalcode – Open4education Ramda also makes available some cool and very useful functions
  32. 32. Globalcode – Open4education Avoiding you to rewrite the same stuff that you always have to
  33. 33. Globalcode – Open4education Ramda functions are divided into various categories
  34. 34. Globalcode – Open4education Ramda functions categories Function Math List Logic Object Relation
  35. 35. Globalcode – Open4education Function functions // Always return the same thing, ignoring arguments const name = R.always('Derek') name('Willian') //=> Derek // Functional if then else, a.k.a. Maybe Monad const findName = R.ifElse( R.has('name'), R.prop('name'), R.always('No name') ) findName({ title: 'Mr.', name: 'Derek' }) //=> Derek findName({ title: 'Mr.' }) //=> No name // Pipe functions left-to-right. First function can have any arity // Others must have arity of exactly one const calculate = R.pipe(Math.pow, R.negate, R.inc); calculate(3, 2); // -(3^2) + 1
  36. 36. Globalcode – Open4education Math functions // Addition R.add(1, 2) //=> 3 // Subtraction R.subtract(2, 1) //=> 1 // Sum all elements R.sum([1, 1, 1]) //=> 3 // Increment R.inc(41) //=> 42 // Decrement R.dec(43) //=> 42 // Calculate the mean R.mean([2, 7, 9]) //=> 6
  37. 37. Globalcode – Open4education List functions // Check if all elements match a predicate R.all(R.gt(4), [1, 2, 3]) //=> true // Check if a number is inside a list R.contains(3, [1, 2, 3]) // Drop elements from start R.drop(1, ['foo', 'bar', 'baz']) //=> ['bar', 'baz'] // Find elements using a predicate const list = [{a: 1}, {a: 2}, {a: 3}] R.find(R.propEq('a', 2))(list) //=> {a: 2} R.find(R.propEq('a', 4))(list) //=> undefined // Flatten a list of list into a single list const list = [1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]] R.flatten(list) //=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
  38. 38. Globalcode – Open4education Logic functions // Combine predicates into a single function var gt10 = x => x > 10 var even = x => x % 2 === 0 var gt10even = R.both(gt10, even) gt10even(100) //=> true gt10even(101) //=> false // Functional switch case (aka. pattern matching?) var whatHappensAtTemperature = R.cond([ [R.equals(0), R.always('water freezes at 0°C')], [R.equals(100), R.always('water boils at 100°C')], [R.T, temp => 'nothing special happens at ' + temp + '°C'] ]) whatHappensAtTemperature(0) //=> 'water freezes at 0°C' whatHappensAtTemperature(50) //=> 'nothing special happens at 50°C' whatHappensAtTemperature(100) //=> 'water boils at 100°C'
  39. 39. Globalcode – Open4education Object functions // Add a key and value to an already existing object R.assoc('c', 3, {a: 1, b: 2}) //=> {a: 1, b: 2, c: 3} // Remove a key from an already existing object R.dissoc('b', {a: 1, b: 2, c: 3}) //=> {a: 1, c: 3} // Do the same with a nested path R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}) //=> {a: {b: {c: 42}}} // Check if an object contains a key var hasName = R.has('name') hasName({name: 'alice'}) //=> true hasName({name: 'bob'}) //=> true hasName({}) //=> false // Pick some properties from objects var abby = {name: 'Abby', age: 7, hair: 'blond', grade: 2} var fred = {name: 'Fred', age: 12, hair: 'brown', grade: 7} R.project(['name', 'grade'], [abby, fred]) //=> [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}]
  40. 40. Globalcode – Open4education Relation functions // Lots of comparison functions // Kinda tricky, but also kinda natural R.gt(2, 1) // 2 > 1 R.gt(2, 2) // 2 > 2 R.gte(2, 2) // 2 >= 2 R.gte(3, 2) // 3 >= 2 R.lt(2, 1) // 2 < 1 R.lt(2, 2) // 2 < 2 R.lte(2, 2) // 2 <= 2 R.lte(3, 2) // 3 <= 2 // Restrict a number to a range R.clamp(1, 10, -1) // => 1 R.clamp(1, 10, 11) // => 10 // Intersect two lists R.intersection([1,2,3,4], [7,6,4,3]) //=> [4, 3]
  41. 41. Globalcode – Open4education Ramda works well with Promise
  42. 42. Globalcode – Open4education Ramda and Promises app.get('/v1/plants/:id', auth.active, (req, res) => { db.plants.find({ id: req.params.id }) .then(R.head) .then(R.bind(res.send, res)) })
  43. 43. Globalcode – Open4education Ramda and Promises function timesValues (number) { return spot(number) .then(spot => db.collection('zone_type_values') .findOne({ id: spot.zone_type_value_id }) .then(R.prop('time_values')) .then(R.assoc('timesValues', R.__, spot)) .then(R.pickAll(['id', 'name', 'timesValues'])) ) }
  44. 44. Globalcode – Open4education Thanks for watching Questions? github.com/derekstavis twitter.com/derekstavis facebook.com/derekstavis

×