$30 off During Our Annual Pro Sale. View Details »

Functional Programming: What? Why? How?

Functional Programming: What? Why? How?

Presented at HolyJS 2017 (https://holyjs-piter.ru/en/talks/functional-programming-in-js-what-why-how/)

Functional programming has become a hot topic in the JS community, leaving many JavaScripters wondering: What's all the hype about? What do functional programs look like, and why might I prefer them to imperative/object-oriented code? How do I get started writing code in a functional style?

If you've been asking yourself these questions, you'll enjoy this gentle, practical intro to functional programming. We'll explore the advantages and basic principles of the paradigm, in which holy, pure functions deliver us from the evils of mutable state. We'll see how rejecting side-effects and mutability in our code can avoid a lot of common JS headaches. And we'll learn how to use core JS features as well as some popular FP libraries like Mori and Ramda to start writing our own functional programs.

Anjana Sofia Vakil

June 03, 2017
Tweet

More Decks by Anjana Sofia Vakil

Other Decks in Programming

Transcript

  1. Functional Programming:
    What? Why? How?
    @AnjanaVakil
    HolyJS 2017

    View Slide

  2. Who?
    @AnjanaVakil

    View Slide

  3. The Recurse Center
    https://www.recurse.com/

    View Slide

  4. What is functional programming?

    View Slide

  5. What is functional programming?
    a buzz-wordy trend

    View Slide

  6. pure functor
    side effect
    monad
    monoid
    compose
    curry
    λ
    immutable
    stateless
    lazy
    referential transparency
    higher-order

    View Slide

  7. pure functor
    side effect
    monad
    monoid
    compose
    curry
    λ
    immutable
    stateless
    lazy
    referential transparency
    higher-order
    ???

    View Slide

  8. What is functional programming?
    a coding style
    supported by some languages

    View Slide

  9. Clojure
    Haskell
    JavaScript!
    Erlang
    Elm
    Scala
    F#
    OCaml

    View Slide

  10. What is functional programming?
    a programming paradigm
    (worldview, mindset)

    View Slide

  11. Imperative
    follow my commands
    do this, then that
    Object-Oriented
    keep state to yourself
    send/receive messages
    Declarative
    this is what I want
    I don't care how you do it
    Functional
    ???

    View Slide

  12. What is functional programming?
    one simple idea

    View Slide

  13. https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming

    View Slide

  14. pure functions
    only input in
    only output out

    View Slide

  15. Not pure:
    var name = "Saint Petersburg";
    function greet() {
    console.log("Hello, " + name + "!");
    }
    greet(); // Hello, Saint Petersburg!
    name = "HolyJS";
    greet(); // Hello, HolyJS!

    View Slide

  16. Pure:
    function greet(name) {
    return "Hello, " + name + "!";
    }
    greet("Saint Petersburg");
    // "Hello, Saint Petersburg!"
    greet("HolyJS");
    // "Hello, HolyJS!"

    View Slide

  17. Why functional programming?

    View Slide

  18. Why functional programming?
    more predictable, safer

    View Slide

  19. Why functional programming?
    easier to test/debug

    View Slide

  20. Why functional programming?
    makes you look/feel smart
    is The Best™ paradigm

    View Slide

  21. Why functional JavaScript?

    View Slide

  22. Why functional JavaScript?
    object-oriented JS gets tricky
    (prototypes? this?!?)

    View Slide

  23. Why functional JavaScript?
    established community/tools

    View Slide

  24. OK, let’s do it!

    View Slide

  25. OK, let’s do it!
    ...how?

    View Slide

  26. Do everything with functions
    program === function(s)

    View Slide

  27. Imperative:
    var city = "St. Petersburg";
    var greeting = "Hi";
    console.log(greeting + ", " + city + "!");
    // Hi, St. Petersburg!
    greeting = "Привет";
    console.log(greeting + ", " + city + "!");
    // Привет, St. Petersburg!

    View Slide

  28. Functional:
    function greet(greeting, name) {
    return greeting + ", " + name + "!";
    }
    greet("Hi", "St. Petersburg");
    // "Hi, St. Petersburg!"
    greet("Привет", "HolyJS");
    // "Привет, HolyJS!"

    View Slide

  29. Avoid side effects
    do nothing but return output

    View Slide

  30. Side effects:
    var conf = {name: "SaintJS", date: 2017};
    function renameConf(newName) {
    conf.name = newName;
    console.log("Renamed!");
    }
    renameConf("HolyJS"); // Renamed!
    conf; // {name: "HolyJS", date: 2017}

    View Slide

  31. No side effects:
    var conf = {name: "SaintJS", date: 2017};
    function renameConf(oldConf, newName) {
    return {name: newName, date: oldConf.date}
    }
    var newConf = renameConf(conf, "HolyJS");
    newConf; // {name: "HolyJS", date: 2017}
    conf; // {name: "SaintJS", date: 2017}

    View Slide

  32. Avoid mutability
    don't change in-place;
    instead, replace

    View Slide

  33. Mutation (dangerous!):
    var numSysts = ["Roman", "Arabic", "Chinese"];
    numSysts[1] = "Hindu-" + numSysts[1];
    numSysts;
    // ["Roman", "Hindu-Arabic", "Chinese"]

    View Slide

  34. No mutation (safer!):
    const numSysts = ["Roman", "Arabic", "Chinese"];
    const newNumSysts = numSysts.map((num) => {
    if (num === "Arabic") { return "Hindu-" + num; }
    else { return num; }
    });
    newNumSysts;//["Roman", "Hindu-Arabic", "Chinese"]
    numSysts; //["Roman", "Arabic", "Chinese"]

    View Slide

  35. 0 1 2 3 4 5 6 7
    foo
    Mutable data

    View Slide

  36. 8 1 2 3 4 5 6 7
    foo
    Mutable data

    View Slide

  37. 0 1 2 3 4 5 6 7
    foo
    Immutable data

    View Slide

  38. 0 1 2 3 4 5 6 7
    foo
    8 1 2 3 4 5 6 7
    too
    Immutable data

    View Slide

  39. 0 1 2 3 4 5 6 7
    foo
    8 1 2 3 4 5 6 7
    too
    Immutable data (inefficient)

    View Slide

  40. Use persistent data structures
    for efficient immutability

    View Slide

  41. 0 1 2 3 4 5 6 7
    foo
    Immutable data (efficient)

    View Slide

  42. 0 1 2 3 4 5 6 7
    foo
    Immutable data (efficient)

    View Slide

  43. 0 1 2 3
    foo
    4 5 6 7
    1
    8
    too
    Immutable data (efficient)

    View Slide

  44. 0 1 2 3
    foo
    4 5 6 7
    1
    8
    too
    Persistent (immutable) data structures
    structural
    sharing

    View Slide

  45. Mori
    https://swannodette.github.io/mori
    var f = mori.vector(1,2);
    var t = mori.conj(f, 3);
    ● ClojureScript port
    ● Functional API
    ● Fast
    Immutable.js
    https://facebook.github.io/immutable-js
    var f = Immutable.List.of(1,2);
    var t = f.push(3);
    ● JS through & through
    ● Public methods
    ● A bit smaller than Mori
    Persistent data structures

    View Slide

  46. Don’t iterate
    recurse

    View Slide

  47. Iteration:
    function sum (numbers) {
    let total = 0;
    for (i = 0; i < numbers.length; i++) {
    total += numbers[i];
    }
    return total;
    }
    sum([0,1,2,3,4]); // 10

    View Slide

  48. Recursion:
    function sum (numbers) {
    if (numbers.length === 1) {
    return numbers[0];
    } else {
    return numbers[0] + sum(numbers.slice(1));
    }
    }
    sum([0,1,2,3,4]); // 10

    View Slide

  49. Don’t loop
    use map, reduce, filter

    View Slide

  50. Filter
    Figure adapted from
    http://www.datasciencecentral.com/forum/topics/what-is-map-reduce

    View Slide

  51. Use higher-order functions
    functions with functions
    as inputs/outputs

    View Slide

  52. Closures:
    function makeAdjectifier(adjective) {
    return function (noun) {
    return adjective + " " + noun;
    };
    }
    var holify = makeAdjectifier("holy");
    holify("JS"); // "holy JS"
    holify("cow"); // "holy cow"

    View Slide

  53. Flow data through functions
    outputs become inputs become outputs

    View Slide

  54. Outputs become next inputs:
    var ender = (ending) => (input) => input + ending;
    var adore = ender(" rocks");
    var announce = ender(", y'all");
    var exclaim = ender("!");
    var hypeUp = (x) => exclaim(announce(adore(x)));
    hypeUp("JS"); // "JS rocks, y'all!"
    hypeUp("FP"); // "FP rocks, y'all!"

    View Slide

  55. Function composition/pipelining:
    var r = require("ramda");
    var rtlHype = r.compose(adore, announce, exclaim);
    rtlHype("FP"); // "FP!, y'all rocks"
    var ltrHype = r.pipe(adore, announce, exclaim);
    ltrHype("FP"); // "FP rocks, y'all!"

    View Slide

  56. FP libraries for JS
    ● Mori (swannodette.github.io/mori)
    ● Immutable.js (facebook.github.io/immutable-js)
    ● Ramda (ramdajs.com)
    ● Underscore (underscorejs.org)
    ● Lodash (lodash.com)
    ● ...and more!

    View Slide

  57. Further reading/watching
    Code Words by the Recurse Center (codewords.recurse.com)
    ● Mary Rose Cook, "An introduction to functional programming"
    ● Sal Becker, "This just isn't functional"
    ● Patrick Dubroy, "Immutability is not enough"
    J. Kerr, “Functional Principles for OO Development”, GOTO Chicago '14
    youtu.be/GpXsQ-NIKXY
    Me, "Immutable data structures for functional JS", JSConf EU '17
    youtu.be/Wo0qiGPSV-s
    D. Nolen, “Immutability, interactivity & JS”, FutureJS '14 youtu.be/mS264h8KGwk
    L. Byron, “Immutable Data & React”, React.js Conf '15 youtu.be/I7IdS-PbEgI
    B. Stokke, "The Miracle of Generators", GOTO Chicago '16 youtu.be/6mCkLZ0cwAI

    View Slide

  58. Thanks for listening!
    I’m @AnjanaVakil
    Huge thanks to:
    Mary Rose Cook, Sal Becker,
    Khalid Ali & The Recurse Center
    HolyJS organizers

    View Slide