Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Who? @AnjanaVakil

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

What is functional programming?

Slide 5

Slide 5 text

What is functional programming? a buzz-wordy trend

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Clojure Haskell JavaScript! Erlang Elm Scala F# OCaml

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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 ???

Slide 12

Slide 12 text

What is functional programming? one simple idea

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

pure functions only input in only output out

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Why functional programming?

Slide 18

Slide 18 text

Why functional programming? more predictable, safer

Slide 19

Slide 19 text

Why functional programming? easier to test/debug

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Why functional JavaScript?

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Why functional JavaScript? established community/tools

Slide 24

Slide 24 text

OK, let’s do it!

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Avoid side effects do nothing but return output

Slide 30

Slide 30 text

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}

Slide 31

Slide 31 text

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}

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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"]

Slide 35

Slide 35 text

0 1 2 3 4 5 6 7 foo Mutable data

Slide 36

Slide 36 text

8 1 2 3 4 5 6 7 foo Mutable data

Slide 37

Slide 37 text

0 1 2 3 4 5 6 7 foo Immutable data

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Use persistent data structures for efficient immutability

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

Don’t iterate recurse

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Don’t loop use map, reduce, filter

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

Flow data through functions outputs become inputs become outputs

Slide 54

Slide 54 text

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!"

Slide 55

Slide 55 text

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!"

Slide 56

Slide 56 text

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!

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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