Functional Javascript, CVjs

1,092 views
915 views

Published on

Javascript Meetup in Charlottesville for CVjs.

http://www.meetup.com/Central-Virginia-Javascript-Enthusiasts-CVJSE/events/132911552/

Published in: Technology, Business
1 Comment
2 Likes
Statistics
Notes
No Downloads
Views
Total views
1,092
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
36
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Functional Javascript, CVjs

  1. 1. Talk Functional Javascript! //+ CV.js :: September 18th, 2013 Kevin Welcher
  2. 2. Shout Out
  3. 3. Shout Out Something about Camp?
  4. 4. 10k Feet • [Underscore.js / Lodash.js] • Functional Concepts • Composition • Currying • [Demo]
  5. 5. Underscore.js Lodash.js
  6. 6. Highlights • reduce • map • pluck • filter • find
  7. 7. reduce • The grandaddy, most iterators can be made out of reduce • “Reduce a list to a new object”
  8. 8. map • Bread and butter iterator • Used to transform a list of elements from one type to another • Whatever is returned within the iterator is the new object
  9. 9. pluck • Iterates over a list of objects and returns a new list made of the specified property from each object • A common use for map • IE: plucking the name from an array of people objects
  10. 10. filter • Only allows values that pass a predicate into the new list • As with all these methods, it returns copies of the data
  11. 11. find • Accepts a predicate and returns the first item that passes the predicate
  12. 12. Much, much more... • Many predicates (isArray, isNull, ...) • keys / values • groupBy • result • array methods • union / intersection • chain / compose • extend / defaults • simple templates • pick / omit
  13. 13. FP vs OO • The language of the... language • How complexity is hidden • How data is stored
  14. 14. Functional Concepts
  15. 15. Function purity • Deterministic • Does not depend on external state • Does not depend on IO • Does not cause side effects
  16. 16. Function purity var View = Backbone.View.extend({ initialize: function() { this.generateList(); }, generateList: function() { this.list = new Backbone.Collection([ {name: 'sally'}, {name: 'joe'} ]); } });
  17. 17. Function purity var View = Backbone.View.extend({ initialize: function() { this.list = this.generateList(); }, generateList: function() { return new Backbone.Collection([ {name: 'sally'}, {name: 'joe'} ]); } });
  18. 18. Functions as data • First class citizens • Identified by their returns • Modifiable
  19. 19. Functions as building blocks Functions which consume the return value of the function that follows. Composition:
  20. 20. Functions as building blocks a() b() c() a(b(c(x))) === compose(a, b, c)(x) Composition
  21. 21. Functions as building blocks function add1 (x) { return x + 1; } var add3 = compose(add1, add1, add1); add3(0); //> 3
  22. 22. Functions as building blocks function add1 (x) { return x + 1; } var add3 = compose(add1, add1, add1); add3(0); //> 3 0
  23. 23. Functions as building blocks function add1 (x) { return x + 1; } var add3 = compose(add1, add1, add1); add3(0); //> 3 01
  24. 24. Functions as building blocks function add1 (x) { return x + 1; } var add3 = compose(add1, add1, add1); add3(0); //> 3 012
  25. 25. Functions as building blocks function add1 (x) { return x + 1; } var add3 = compose(add1, add1, add1); add3(0); //> 3 0123
  26. 26. Functions as building blocks function not (x) { return !x; } var boolify = compose(not, not); not(not({})); boolify({}); //> true
  27. 27. Functions as building blocks function addTitle (x) { return ‘Mr. ‘ + x; } function addSalutation (x) { return ‘G’day, ‘ + x; } var meetAndGreet = compose(addSalutation, addTitle); addSalutation(addTitle('Baggins')); meetAndGreet('Baggins'); //> G’day, Mr. Baggins
  28. 28. Functions as building blocks function add (x, y) { return x + y; } var add1 = compose(???); //> profit
  29. 29. Currying “Taking a function that takes multiple arguments and transforming it to a chain of functions that accept a single argument.” - Wikipedia
  30. 30. Notation //+ <method name> :: type -> type -> type
  31. 31. Notation //+ <method name> :: type -> type -> type A function that take takes an argument and returns a value of type
  32. 32. Notation //+ <method name> :: type -> type -> type A function that take takes an argument and returns a value of type integer -> integer A function that takes in a single argument of type integer The return type of integer. Since nothing follows, it is the final return
  33. 33. Notation //+ <method name> :: type -> type -> type A function that take takes an argument and returns a value of type
  34. 34. Notation //+ <method name> :: type -> type -> type The ultimate return value of a function
  35. 35. //+ not :: a -> boolean function not (x) { return !x; } not(true) //> false
  36. 36. //+ not :: a -> boolean function not (x) { return !x; } not(true) //> false The a (or any other lower case letter) means we don’t care about the type.
  37. 37. //+ add :: a, a -> a function add(x, y) { return x + y; } add(1, 2); //> 3
  38. 38. //+ add :: a, a -> a function add(x, y) { return x + y; } add(1, 2); //> 3 I am abusing notation :(
  39. 39. “Taking a function that takes multiple arguments and transforming it to a chain of functions that accept a single argument.” - Wikipedia
  40. 40. //+ add :: a, a -> a //+ add :: a -> a -> a
  41. 41. //+ add :: a -> a -> a function add(x) { return function (y) { return x + y; }; } add(1)(2); //> 3 ed
  42. 42. //+ add :: a -> a -> a function add(x) { return function (y) { return x + y; }; } add(1)(2); //> 3 ed
  43. 43. //+ add :: a -> a -> a //+ add :: 1 -> a -> a //+ add1 :: integer -> integer var add1 = add(1); add1(2); //> 3
  44. 44. //+ add :: a -> a -> a //+ add :: ‘Mr. ‘ -> a -> a //+ addTitle :: string -> string var addTitle = add('Mr. '); addTitle('Baggins'); //> Mr. Baggins
  45. 45. Problem
  46. 46. That _ is ugly //+ add :: a -> a -> a function add(x) { return function (y) { return x + y; }; } add(1)(2); //> 3
  47. 47. autoCurry A custom function that automatically curries for you. For each parameter of a function, it returns a new function.
  48. 48. That _ is ugly //+ add :: a -> a -> a var add = function(x, y) { return x + y; }.autoCurry(); add(1, 2); //> 3 add(1)(2); //> 3 Awww yissss
  49. 49. Cool Story Bru...
  50. 50. Let Me ConvinceYou With...
  51. 51. More Examples!
  52. 52. reduce //+ reduce :: fn -> a -> array -> a var reduce = function (fn, start, list) { // ... }.autoCurry();
  53. 53. reduce //+ reduce :: fn -> a -> array -> a var reduce = function (fn, start, list) { // ... }.autoCurry(); function (cnrt, val, index, list) { // ... }
  54. 54. Sum all the numbers in a list?
  55. 55. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(function (crnt, val, index, list) { return crnt + val; }, 0, items); //> 6
  56. 56. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(function (crnt, val, index, list) { return crnt + val; }, 0, items); //> 6 We don’t use these two arguments so we can omit them
  57. 57. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(function (crnt, val) { return crnt + val; }, 0, items); //> 6
  58. 58. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(function (crnt, val) { return crnt + val; }, 0, items); //> 6 This function looks familiar...
  59. 59. //+ add :: a -> a -> a var add = function(x, y) { return x + y; }.autoCurry();
  60. 60. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(function (x, y) { return x + y; }, 0, items); //> 6
  61. 61. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(function (x, y) { return x + y; }, 0, items); //> 6 Instead of inlining the function, just pass the function’s pointer
  62. 62. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(add, 0, items); //> 6
  63. 63. var items = [1, 2, 3]; //+ reduce :: fn -> a -> array -> a reduce(add, 0, items); //> 6 Cool! But isn’t reduce curried? Can we make this into a generic function?
  64. 64. var items = [1, 2, 3]; //+ reduce :: add -> 0 -> array -> a //+ sum :: array -> integer var sum = reduce(add, 0); sum(items); //> 6
  65. 65. Demo https://gist.github.com/kaw2k/6312261
  66. 66. Lessons Learned?
  67. 67. Keep your methods short and to the point It is easier to build things if your building blocks are small
  68. 68. Stick your data as the last parameter reduce = function (fn, starting value, data) function (general, ..., specific)
  69. 69. Optional parameters are hard Make a general function and curry it to take optional stuff
  70. 70. Functional purity is pretty cool • Easier to maintain • Easier to reason • Easier to test • Easier to transport
  71. 71. Obligatory Marketing (We are hiring)

×