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. Learn
    Functional Programming
    (by implementing a SQL DSL)
    in JavaScript and PHP
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  2. 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

    View Slide

  3. Main Street, Carrboro
    N E W M E D I A C A M P A I G N S
    Tuesday, January 24, 12

    View Slide

  4. Objectives
    1. Grok functional programming fundamentals
    2. Familiarity with underscore.(js|php)
    3. Transfer SQL knowledge to FP
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  5. Why should you care
    about
    Functional Programming?
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  6. $(“p”).each(function(){
    $(this).wrap(“”);
    });
    1. We already use
    functional programming
    techniques
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  7. 2. Our code consumes data.
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  8. with fewer bugs
    and think differently
    3. You’ll write less code
    about programming.
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  9. So, what is
    Functional Programming?
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  10. λ Church
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  11. (McCarthy)
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  12. Functions are data.
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  13. // JavaScript here
    // php here
    Title here.
    Tuesday, January 24, 12

    View Slide

  14. Functions are data.
    var logMessage = function(){
    console.log(“Hello, world.”);
    };
    logMessage();
    $logMessage = function(){
    echo(“Hello, world.”);
    };
    $logMessage();
    Tuesday, January 24, 12

    View Slide

  15. Functions can be passed to
    Executor functions.
    var executor = function(aFunction){
    aFunction();
    }
    executor(logMessage);
    $executor = function($aFunction){
    $aFunction();
    };
    $executor($logMessage);
    Tuesday, January 24, 12

    View Slide

  16. jQuery’s API is awesome thanks to
    Executor functions.
    $(‘h1’).click(function(){
    console.log(“Hello, world”);
    });
    @KrisJordan
    $(“p”).each(function(){
    $(this).wrap(“”);
    });
    Tuesday, January 24, 12

    View Slide

  17. underscore.(js|php)
    60-some classic functions
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  18. @KrisJordan
    Tuesday, January 24, 12

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  31. pluralFn(
    item
    item
    item
    , singularFn );
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  32. underscore.(js|php)
    60-some classic functions
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  33. pluralFn(
    item
    item
    item
    , singularFn );
    executor
    how can we do
    better here?
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  34. Executor Function
    jQuery(‘h1’).click( );
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  35. Executor Function
    Anonymous Function
    $(‘h1’).click(function(){
    $(this).toggleClass(“selected”);
    });
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

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

    View Slide

  37. Executor Function
    Anonymous Function
    Function Variable
    $(‘h1’).click(toggleClass(“selected”));
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  38. 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

    View Slide

  39. 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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

  44. Refactor to Generator
    @KrisJordan
    Anonymous
    Function
    Function
    Variable
    Generator
    Function
    refactor for
    reuse
    refactor for
    parameters
    Tuesday, January 24, 12

    View Slide

  45. 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

    View Slide

  46. 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

    View Slide

  47. 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

    View Slide

  48. Our Goal
    select([“p.first”,
    “p.last”,
    “p.games”,
    “p.points”],
    orderBy(“p.last”,
    where(equals(c(“p.games”),19),
    from(“players”,”p”,tables))));
    @KrisJordan
    Tuesday, January 24, 12

    View Slide

  49. Live coding.
    Tuesday, January 24, 12

    View Slide

  50. 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

    View Slide

  51. Tuesday, January 24, 12

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide