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

Functional Programming Fundamentals in JS & PHP

krisjordan
January 24, 2012

Functional Programming Fundamentals in JS & PHP

Slide deck from talk given at Triangle JS / PHP / MySQL meetup.

krisjordan

January 24, 2012
Tweet

Other Decks in Programming

Transcript

  1. Who am I? • Kris Jordan • Founder at New

    Media Campaigns • Ping me via... • Twitter: @KrisJordan • GitHub: KrisJordan • Email: [email protected] • KrisJodan.com @KrisJordan Tuesday, January 24, 12
  2. Main Street, Carrboro N E W M E D I

    A C A M P A I G N S Tuesday, January 24, 12
  3. Objectives 1. Grok functional programming fundamentals 2. Familiarity with underscore.(js|php)

    3. Transfer SQL knowledge to FP @KrisJordan Tuesday, January 24, 12
  4. with fewer bugs and think differently 3. You’ll write less

    code about programming. @KrisJordan Tuesday, January 24, 12
  5. Functions are data. var logMessage = function(){ console.log(“Hello, world.”); };

    logMessage(); $logMessage = function(){ echo(“Hello, world.”); }; $logMessage(); Tuesday, January 24, 12
  6. Functions can be passed to Executor functions. var executor =

    function(aFunction){ aFunction(); } executor(logMessage); $executor = function($aFunction){ $aFunction(); }; $executor($logMessage); Tuesday, January 24, 12
  7. jQuery’s API is awesome thanks to Executor functions. $(‘h1’).click(function(){ console.log(“Hello,

    world”); }); @KrisJordan $(“p”).each(function(){ $(this).wrap(“<marquee/>”); }); Tuesday, January 24, 12
  8. map( 3 2 1 , function(item){ return item * item;

    } ); @KrisJordan Tuesday, January 24, 12
  9. map( 3 2 1 , function(item){ return item * item;

    } ); @KrisJordan Tuesday, January 24, 12
  10. map( 3 2 1 , function(item){ return item * item;

    } ); 9 @KrisJordan Tuesday, January 24, 12
  11. map( 3 2 1 , function(item){ return item * item;

    } ); 9 4 @KrisJordan Tuesday, January 24, 12
  12. map( 3 2 1 , function(item){ return item * item;

    } ); 9 4 1 @KrisJordan Tuesday, January 24, 12
  13. map( 3 2 1 , function(item){ return item * item;

    } ); 9 4 1 return to caller @KrisJordan Tuesday, January 24, 12
  14. map implemented var map = function(collection, fn) { var rv

    = []; for(var i = 0; i < collection.length; i++){ var item = collection[i]; rv.push(fn(item)); } return rv; } $map = function($collection, $fn) { $rv = array(); for($i = 0; $i < count($collection); i++){ $item = $collection[$i]; $rv[] = $fn($item); } return $rv; } Tuesday, January 24, 12
  15. filter( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); @KrisJordan Tuesday, January 24, 12
  16. filter( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); true? yes 3 @KrisJordan Tuesday, January 24, 12
  17. filter( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); true? no! 3 @KrisJordan Tuesday, January 24, 12
  18. filter( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); true? yes 3 1 @KrisJordan Tuesday, January 24, 12
  19. filter( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); 3 1 return to caller @KrisJordan Tuesday, January 24, 12
  20. pluralFn( item item item , singularFn ); executor how can

    we do better here? @KrisJordan Tuesday, January 24, 12
  21. Executor Function Anonymous Function Function Variable var toggleSelected = function(){

    $(this).toggleClass(“selected”); }; $(‘h1’).click(toggleSelected); @KrisJordan Tuesday, January 24, 12
  22. Executor Function Anonymous Function Function Variable Generator Function var toggleClass

    = function(klass){ return function(){ $(this).toggleClass(klass); }; }; $(‘h1’).click(toggleClass(“selected”)); Tuesday, January 24, 12
  23. Functions can be returned by Generator functions. var genMessageFn =

    function(msg) { return function(){console.log(msg);}; }; jQuery(‘h1’).click(genMessageFn(“Hi!”)); $genMessageFn = function($msg) { return function()use($msg){echo($msg);}; }; $executor($genMessageFn(“Hi!”)); Tuesday, January 24, 12
  24. Something smells fishy, var genMessageFn = function(msg) { return function(){console.log(msg);};

    }; $(‘h1’).click(genMessageFn(“Hi!”)); $genMessageFn = function(msg) { return function()use($msg){echo($msg);}; }; $executor($genMessageFn(“Hi!”)); doesn’t `msg` pop off the stack? Tuesday, January 24, 12
  25. Functions can be closures. They “trap” var refs into a

    fn’s scope. JS closures are implicit. PHP closures are explicit. function() use($msg) {...} Tuesday, January 24, 12
  26. Executor Function Anonymous Function var toggleClass = function(klass){ return function(){

    $(this).toggleClass(klass); }; }; $(‘h1’).click(toggleClass(“selected”)); Function Variable Generator Function “Trapped” in Scope by Closure Tuesday, January 24, 12
  27. Closures in OOP terms: native, minimal Command pattern class MsgCommand

    { private $_msg; function __construct($msg) { $this->$_msg = $msg; } function exec() { echo $this->_msg; } } $cmd = new MsgCommand(“OOP”); $cmd->exec(); $msgCommand = function($msg) { return function()use($msg) { echo $msg; }; }; $cmd = $msgCommand(“FP”); $cmd(); OOP FP @KrisJordan Tuesday, January 24, 12
  28. Refactor to Generator @KrisJordan Anonymous Function Function Variable Generator Function

    refactor for reuse refactor for parameters Tuesday, January 24, 12
  29. var toggleClassSelected = function(){ $(this).toggleClass(“selected”); }; $(‘h1’).click(toggleClassSelected); $(‘h1’).click(function(){ $(this).toggleClass(“selected”); });

    var toggleClass = function(klass){ return function(){ $(this).toggleClass(klass); }; }; $(‘h1’).click(toggleClass(“selected”)); Anon Function Function Variable Generator Function refactor for reuse refactor for parameters refactor for reuse refactor for parameters Tuesday, January 24, 12
  30. Let’s Implement a SQL DSL SELECT p.first, p.last, p.games, p.points

    FROM players AS p WHERE p.games = 19 ORDER BY p.last @KrisJordan Tuesday, January 24, 12
  31. Let’s Implement a SQL DSL SELECT p.first, p.last, p.games, p.points

    FROM players AS p WHERE p.games = 19 ORDER BY p.last _.filter _.sortBy _.map _.map @KrisJordan Tuesday, January 24, 12
  32. Recap • Functions are data • Closures “trap” variable references

    in scope, useful for generating functions • Write singular function generators, leverage with plural executor functions • Underscore provides great executor functions for processing data @KrisJordan Tuesday, January 24, 12
  33. any( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); Tuesday, January 24, 12
  34. any( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); true? yes true Tuesday, January 24, 12
  35. any( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); true? yes true return to caller Tuesday, January 24, 12
  36. reject( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); Tuesday, January 24, 12
  37. reject( 3 2 1 ,function(item){ return item % 2 ===

    1; } ); 2 return to caller Tuesday, January 24, 12
  38. reduce( 3 2 1 , function(memo,item){ return memo + item;

    } ); 0 , 0 memo Tuesday, January 24, 12
  39. reduce( 3 2 1 , ); 0 , 0 memo

    function(memo,item){ return 0+3; } Tuesday, January 24, 12
  40. reduce( 3 2 1 , ); 3 , 0 memo

    function(memo,item){ return 0+3; } Tuesday, January 24, 12
  41. reduce( 3 2 1 , ); 3 , 0 memo

    function(memo,item){ return 3+2; } Tuesday, January 24, 12
  42. reduce( 3 2 1 , ); 5 , 0 memo

    function(memo,item){ return 3+2; } Tuesday, January 24, 12
  43. reduce( 3 2 1 , ); 5 , 0 memo

    function(memo,item){ return 5+1; } Tuesday, January 24, 12
  44. reduce( 3 2 1 , ); 6 , 0 memo

    function(memo,item){ return 5+1; } Tuesday, January 24, 12
  45. reduce( 3 2 1 , function(memo,item){ return memo + item;

    } ); 6 , 0 memo return to caller Tuesday, January 24, 12