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

Functions, combinators, and decorators in JavaS...

Avatar for Seth House Seth House
February 19, 2013

Functions, combinators, and decorators in JavaScript

A book review of JavaScript Allongé

Slide notes are in the .rst source.

Slides: https://github.com/whiteinge/presentations/tree/master/utahjs_2013-02-19_functions-combinators

Video: http://www.youtube.com/watch?v=XqbG6-l_boY

Avatar for Seth House

Seth House

February 19, 2013
Tweet

More Decks by Seth House

Other Decks in Technology

Transcript

  1. Functions, combinators, and decorators in JavaScript Seth House <[email protected]> Utah

    JS 2013-02-19 Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 1 / 37
  2. A review of JavaScript Allongé Outline 1 A review of

    JavaScript Allongé 2 Thinking functionally 3 Function composition 4 Function decomposition 5 Decorators 6 Further reading Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 2 / 37
  3. A review of JavaScript Allongé Reginald Braithwaite https://github.com/raganwald http://allong.es/ Seth

    House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 4 / 37
  4. Thinking functionally Outline 1 A review of JavaScript Allongé 2

    Thinking functionally 3 Function composition 4 Function decomposition 5 Decorators 6 Further reading Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 5 / 37
  5. Thinking functionally The creation of small functions that compose with

    each other. Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 6 / 37
  6. Thinking functionally JavaScript Allongé in a nutshell Learn when it’s

    appropriate to write: return splat(maybe(get(’name’)))(customerList); Instead of: return customerList.map(function (customer) { if (customer) { return customer.name } }); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 6 / 37
  7. Thinking functionally As Little As Possible About Functions, But No

    Less Identities Applying Returns Call by value, call by reference Closures, scope, & environments Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 7 / 37
  8. Thinking functionally Let What if you didn’t have variable assignment?:

    function (diameter) { return diameter * Pi } Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 8 / 37
  9. Thinking functionally Let Wrap within a function that takes an

    argument with the name you want: (function (Pi) { return function (diameter) { return diameter * Pi } })(3.14159265) Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 9 / 37
  10. Thinking functionally Let “Let” is using an IIFE binds values

    to names: (function (Pi) { return function (diameter) { return diameter * Pi } })(3.14159265)(2) //=> 6.2831853 Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 10 / 37
  11. Thinking functionally Pure functions No side-effects It operates on its

    input and returns output No effect on other objects or states Contains no free variables Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 11 / 37
  12. Function composition Outline 1 A review of JavaScript Allongé 2

    Thinking functionally 3 Function composition 4 Function decomposition 5 Decorators 6 Further reading Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 12 / 37
  13. Function composition Combinators Higher-order pure functions that take only functions

    as arguments and return a function. Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 13 / 37
  14. Function composition Why composition? Chaining two or more functions together:

    function cookAndEat (food) { return eat(cook(food)) } Generalized: function compose (a, b) { return function (c) { return a(b(c)) } } var cookAndEat = compose(eat, cook); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 13 / 37
  15. Function composition The for-loop var fruit = [’ orange ’,

    ’ apple ’, ’ pear ’]; var result = []; for (var i = 0; i < fruit.length; i++) { result.push(fruit[i].trim()); } Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 14 / 37
  16. Function composition The map var fruit = [’ orange ’,

    ’ apple ’, ’ pear ’]; var result = fruit.map(function(val) { return val.trim(); }); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 15 / 37
  17. Function composition The composition var fruit = [’ orange ’,

    ’ apple ’, ’ pear ’]; var result = fruit.map(globalize(’trim’)); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 16 / 37
  18. Function composition The “second argument” to array-extras var fruit =

    [’ orange ’, ’ apple ’, ’ pear ’]; var result = fruit.map( Function.prototype.call, String.prototype.trim); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 17 / 37
  19. Function composition Composing for map [’1’, ’2’, ’3’].map(parseFloat); //=> [1,

    2, 3] // HOWEVER: [’1’, ’2’, ’3’].map(parseInt); //=> [ 1, NaN, NaN ] [’1’, ’2’, ’3’].map(applyLast(parseInt, 10)); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 18 / 37
  20. Function decomposition Outline 1 A review of JavaScript Allongé 2

    Thinking functionally 3 Function composition 4 Function decomposition 5 Decorators 6 Further reading Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 19 / 37
  21. Function decomposition One function per task; splitting a function in

    two; extracting sub-functions Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 20 / 37
  22. Function decomposition Partial application function xhr(method, path, data, headers) {

    ... } var post = applyLeft(xhr, ’POST’); var get = applyLeft(xhr, ’GET’); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 20 / 37
  23. Function decomposition Partial application var status = applyLeft(xhr, ’GET’, ’/status’);

    var getJSON = applyRight(xhr, { ’Accept’: ’application/json’, ’Content-Type’: ’application/json’}) Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 21 / 37
  24. Function decomposition Maybe function Model () {}; Model.prototype.setSomething = maybe(function(value)

    { this.something = value; }); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 22 / 37
  25. Function decomposition Currying Extract single-argument functions out of a multi-argument

    function. add(’sum’, 5, 6) Becomes: addCurried(’sum’)(6)(5) Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 24 / 37
  26. Function decomposition Currying function converter(toUnit, factor, offset, input) { ...

    } var milesToKm = converter.curry( ’km’, 1.60936, undefined); var poundsToKg = converter.curry( ’kg’, 0.45460, undefined); var farenheitToCelsius = converter.curry( ’degrees C’, 0.5556, -32); milesToKm(10); //=> 16.09 km poundsToKg(2.5); //=> 1.14 kg farenheitToCelsius(98); //=> 36.67 degrees C Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 25 / 37
  27. Function decomposition Currying function logError(message, inDevmode) { if (inDevmode) console.error(message);

    } function makeLogger(inDevmode) { return function (err) { return logError(err.message || err.toString(), inDevmode); }; } window.onerror = makeLogger(true); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 26 / 37
  28. Decorators Outline 1 A review of JavaScript Allongé 2 Thinking

    functionally 3 Function composition 4 Function decomposition 5 Decorators 6 Further reading Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 27 / 37
  29. Decorators Decorators Takes one function as an argument, returns another

    function, and the returned function is a variation of the argument function. Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 28 / 37
  30. Decorators Example function Todo (name) { ... }; Todo.prototype.do =

    fluent(function () { this.done = true; }); Todo.prototype.undo = fluent(function () { this.done = false; }); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 29 / 37
  31. Decorators Common decorators AKA “advice”, AKA aspect oriented programming, AKA

    Lisp Flavors before after around provided Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 30 / 37
  32. Decorators Common decorators function SomeModel(name) { ... }; SomeModel.prototype.delete =

    isAdmin(user, function () this.delete(); }); Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 31 / 37
  33. Further reading Outline 1 A review of JavaScript Allongé 2

    Thinking functionally 3 Function composition 4 Function decomposition 5 Decorators 6 Further reading Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 32 / 37
  34. Further reading Angus Croll “Some developers like rulebooks and boilerplate—which

    is why we have Java. The joy of JavaScript is rooted in its lack of rigity and the infinite possibilities that this allows for.” —Angus Croll Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 34 / 37
  35. Further reading Functional mixins function() { function withDrama() { this.before(’announce’,

    function() { clearThroat(); }); this.after(’leaving’, function() { slamDoor(); }); } return withDrama; } Seth House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 36 / 37
  36. Further reading Functional reactive programming (FRP) Bacon.js Demo: http://raimohanska.github.com/bacon.js-slides/ Seth

    House <[email protected]> (Utah JS) Functions, combinators, and decorators in JavaScript 2013-02-19 37 / 37