Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Javascript funcional

2,125 views

Published on

  • Be the first to comment

Javascript funcional

  1. 1. Programación funcional con Javascript Leo Soto M. Lecture & Beer 2010, Continuum.
  2. 2. ¿Programación funcional?
  3. 3. Scheme? ML? F#? Haskell?
  4. 4. Dos principios
  5. 5. Principio 1: Olvida las variables. Existen valores y ya.
  6. 6. Principio 1: Olvida las variables. Existen valores y ya. ¡Como en matemáticas!
  7. 7. variables == bugs
  8. 8. x = x + 1
  9. 9. x = x + 1 // -x
  10. 10. x = x + 1 // -x x - x = x - x + 1
  11. 11. x = x + 1 // -x x - x = x - x + 1 0 = 1
  12. 12. x = x + 1 // -x x - x = x - x + 1 0 = 1 WTF
  13. 13. ¡Pero esta charla no trata sobre ese principio!
  14. 14. > var foo = “estamos jodidos”
  15. 15. Principio 1I: Las funciones son valores
  16. 16. Principio 1I: Las funciones son valores primitivos
  17. 17. > var miVariable = 1
  18. 18. > var miVariable = 1 > var otraVariable = miVariable
  19. 19. > var miVariable = 1 > var otraVariable = miVariable > typeof(miVariable) number
  20. 20. > function miFuncion() { return 1 } > typeof(miFuncion) function
  21. 21. > function miFuncion() { return 1 } > typeof(miFuncion) function > var otraFuncion = miFuncion; > typeof(otraFuncion) function
  22. 22. > function miFuncion() { return 1 } > typeof(miFuncion) function > var otraFuncion = miFuncion; > typeof(otraFuncion) function > typeof(otraFuncion()) number
  23. 23. Sintaxis equivalente:
  24. 24. > function f(x, y) { ... } > var f = function(x, y) { ... }
  25. 25. Higher order functions: Funciones que reciben funciones
  26. 26. function time(f) { start = new Date().getTime(); f() end = new Date().getTime(); print(“Milliseconds: ” + (start - end)); }
  27. 27. time(function() { var x = 1; for (var i = 2; i < 1000; i++) { x = x * i; } })
  28. 28. Higher order functions: Funciones que retornan funciones
  29. 29. $(“#edad”).blur( function() { validarRango(this, 18, 65); } );
  30. 30. $(“#edad”).blur( validadorRango(18, 65) );
  31. 31. function validadorRango(a, b) { return function() { var v = $(this).val(); if (v < a || v > b) { alert(“Fuera de rango”); } } }
  32. 32. ¡Closures!
  33. 33. function validadorRango(a, b) { return function() { var v = $(this).val(); if (v < a || v > b) { alert(“Fuera de rango”); } } }
  34. 34. function validadorRango(a, b) { return function() { var v = $(this).val(); if (v < a || v > b) { alert(“Fuera de rango”); } } } ¡No se ejecuta inmediatamente!
  35. 35. function validadorRango(a, b) { return function() { var v = $(this).val(); if (v < a || v > b) { alert(“Fuera de rango”); } } } ¡No se ejecuta inmediatamente! ¡Pero puede acceder a valores de “afuera”!
  36. 36. Es como escribir macros, o plantillas
  37. 37. function validadorRango(a, b) { return function() { var v = $(this).val(); if (v < a || v > b) { alert(“Fuera de rango”); } } }
  38. 38. Primitivas funcionales: map, filter, reduce, any, all, partial
  39. 39. map
  40. 40. > function double(x) { return x * x } > map([1, 2, 3], double) [2, 4, 6]
  41. 41. function map(array, f) { var r = []; for (var i in array) { r.push(f(array[i]); } return r; }
  42. 42. reduce
  43. 43. > function sum(x, y) { return x + y } > function mul(x, y) { return x * y } > reduce([1, 2, 3, 4], 0, sum) 10 > reduce([1, 2, 3, 4], 1, mul) 24
  44. 44. function reduce(array, inicial, f) { var r = inicial for (var i in array) { r = f(r, array[i]); } return r; }
  45. 45. filter
  46. 46. > function par(x) {return x % 2 == 0} > filter([1,2,3,4,5], par) [2, 4]
  47. 47. function filter(array, f) { var r = []; for (var i in array) { if (f(array[i])) { r.push(array[i]); } } return r; }
  48. 48. any
  49. 49. > function par(x) {return x % 2 == 0} > any([1,2,3,4,5], par) true > any([1,3,5], par) false
  50. 50. function any(array, f) { for (var i in array) { if (f(array[i])) { return true; } } return false; }
  51. 51. all
  52. 52. > function par(x) {return x % 2 == 0} > all([1,2,3,4,5], par) false > all([2,4,6], par) true
  53. 53. function all(array, f) { for (var i in array) { if (!f(array[i])) { return false; } } return true; }
  54. 54. function all(array, f) { return !any(array, function(x) { return !f(x) } }
  55. 55. partial
  56. 56. > function mul(x, y) { return x * y } > var double = partial(mul, 2) > double(10) 20
  57. 57. function partial(f) { var fixedArgs = arguments.splice( 1, arguments.length - 1); return function() { return f.apply( this, fixedArgs.concat(arguments) ); }; }
  58. 58. Ejemplos
  59. 59. supers = filter(users, function(u) { return u.superuser; } names = map(supers, function(u) { return u.fullName; });
  60. 60. function getprop(x) { return function(o) { return o[x]; } }
  61. 61. supers = filter(users, getprop(“superuser”)) names = map(supers, getprop(“fullName”))
  62. 62. filter(leagues, function(league) { return any(league.users, getprop(“unapproved”)); });
  63. 63. reduce( map(users, getprop(“age”)), -1, Math.max )
  64. 64. Familiar feeling? map(usuarios, f) =~ SELECT f(usuario) filter(usuarios, f) =~ WHERE f(usuario) any(usuarios, f) =~ SOME(f(usuario)) all(usuarios, f) =~ ALL(f(usuario)) reduce(usuarios, ...) =~ MAX/MIN/AVG...
  65. 65. var phones = [] for (var i in users) { var user = users[i]; var userPhones = []; if (user.phones[0]) { userPhones.push(user.phones[0]); } if (user.phones[1]) { userPhones.push(user.phones[1]); } phones.push(userPhones); }
  66. 66. function first(n, array) { var r = []; for (var i = 0; i < Math.min(array.length, n); i++) { r.push(array[i]); } return r; }
  67. 67. var phones = [] for (var i in users) { phones.push( first(2, users.phones) ); }
  68. 68. function compose(f, g) { return function(x) { return f(g(x)); } }
  69. 69. map(users, compose(partial(first, 2), getprop(“phones”)))
  70. 70. map(users, function(u) { return first(2, u.phones); });
  71. 71. Implementaciones
  72. 72. Javascript 1.6 (Mozilla) array.map, array.filter array.reduce* array.some array.every *Introducido en Javascript 1.8
  73. 73. JQuery $.map, $(“.foo”).map $(“.foo”).filter
  74. 74. Underscore http://documentcloud.github.com/underscore/ _.map, _.reduce, _.detect, _.all, _.any, _.sortBy, ... _.first, _.rest, _.compact, _.flatten, _.uniq, _.zip, _.intersect, ... _.invoke, _.pluck, _.tap, ... _.keys, _.values, ... _.compose, _.bind, _.memoize
  75. 75. ¡Eso!
  76. 76. ¿Preguntas?

×