Slide 1

Slide 1 text

First Steps into Functional Programming https://github.com/vakila/functional-workshop @AnjanaVakil

Slide 2

Slide 2 text

Who am I? @AnjanaVakil

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Who are you? Let's share: - Name - Home base - Programming background/technologies - Interest/experience in FP

Slide 5

Slide 5 text

What is functional programming?

Slide 6

Slide 6 text

What is functional programming? a buzz-wordy trend

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

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Clojure Haskell JavaScript! Erlang Elm Scala F# OCaml

Slide 11

Slide 11 text

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

Slide 12

Slide 12 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 13

Slide 13 text

What is functional programming? one simple idea

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

pure functions only input in only output out

Slide 16

Slide 16 text

Not pure: let name = "Alonzo"; function greet() { console.log("Hello, " + name + "!"); } greet(); // Hello, Alonzo! name = "Alan"; greet(); // Hello, Alan!

Slide 17

Slide 17 text

Pure: function greet(name) { return "Hello, " + name + "!"; } greet("Alonzo"); // "Hello, Alonzo!" greet("Alan"); // "Hello, Alan!"

Slide 18

Slide 18 text

Why functional programming?

Slide 19

Slide 19 text

Why functional programming? more predictable, safer

Slide 20

Slide 20 text

Why functional programming? easier to test/debug

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Why functional JavaScript?

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

Why functional JavaScript? established community/tools

Slide 25

Slide 25 text

OK, let’s do it!

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

Imperative: let name = "Alonzo"; let greeting = "Hi"; console.log(greeting + ", " + name + "!"); // Hi, Alonzo! greeting = "Howdy"; console.log(greeting + ", " + name + "!"); // Howdy, Alonzo!

Slide 29

Slide 29 text

Functional: function greet(greeting, name) { return greeting + ", " + name + "!"; } greet("Hi", "Alonzo"); // "Hi, Alonzo!" greet("Howdy", "Alan"); // "Howdy, Alan!"

Slide 30

Slide 30 text

Avoid side effects do nothing but return output

Slide 31

Slide 31 text

Side effects: let thesis = {name: "Church's", date: 1936}; function renameThesis(newName) { conf.name = newName; console.log("Renamed!"); } renameThesis("Church-Turing"); // Renamed! thesis; //{name: "Church-Turing", date: 1936}

Slide 32

Slide 32 text

No side effects: const thesis = {name: "Church's", date: 1936}; function renameThesis(oldThesis, newName) { return {name: newName, date: oldThesis.date} } const thesis2 = renameThesis(ct,"Church-Turing"); thesis2; // {name: "Church's", date: 1936} thesis; // {name: "Church-Turing", date: 1936}

Slide 33

Slide 33 text

Let’s do it! github.com/vakila/functional-workshop/ tree/master/pure-functions

Slide 34

Slide 34 text

Don’t iterate recurse

Slide 35

Slide 35 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 36

Slide 36 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 37

Slide 37 text

The problem with recursion infinite repetition vs. finite resources

Slide 38

Slide 38 text

The problem with recursion // recursiveInception.js 'use strict'; const recursiveInception = (n) => { if (n === 0) return "a dream"; let dreams = recursiveInception(n-1); return dreams + " within a dream"; } const depth = parseInt(process.argv[2]); console.log(recursiveInception(depth)); $ node recursiveInception.js 30000 /home/anjana/recursiveInception.js:4 const recursiveInception = (n) => { ^ RangeError: Maximum call stack size exceeded at recursiveInception (recursiveInception.js:4:28) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) at recursiveInception (recursiveInception.js:6:16) 1 2 3 4 5 6 7 8 9 10 11 From "Recursion, Iteration & JS: A love story"

Slide 39

Slide 39 text

// tailRecursiveInception.js 'use strict'; const tailRecursiveInception = (n) => { const incept = (n, dreams) => { if (n === 0) return dreams; return incept(n-1, dreams+" within a dream"); } return incept(n, "a dream"); } const depth = parseInt(process.argv[2]); console.log(tailRecursiveInception(depth)); 1 2 3 4 5 6 7 8 9 10 11 12 13 $ nvm use 6 Now using node v6.12.3 $ node --harmony_tailcalls tailRecursiveInception.js 30000 a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a dream within a within a dream within a dream within a dream within ………………….. Tail call optimization From "Recursion, Iteration & JS: A love story"

Slide 40

Slide 40 text

Let’s do it! github.com/vakila/functional-workshop/ tree/master/recursion

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Don’t loop use map, reduce, filter

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Let’s do it! github.com/vakila/functional-workshop/ tree/master/higher-order

Slide 45

Slide 45 text

More higher-order functions outputting functions that "remember" scope

Slide 46

Slide 46 text

Closure: function makeAdjectifier(adjective) { return function (noun) { return adjective + " " + noun; }; } const coolify = makeAdjectifier("cool"); coolify("conference"); // "cool conference" coolify("drink"); // "cool drink"

Slide 47

Slide 47 text

Currying: const curryGreet = (greeting) => { return (name) => { return greeting + ", " + name + "!"; }; }; const greetEng = curryGreet("Hi"); greetEng("Alonzo"); // "Hi, Alonzo!" const greetTex = curryGreet("Howdy"); greetTex("Alonzo"); // "Howdy, Alonzo!"

Slide 48

Slide 48 text

FP & OOP: BFFs? down the closure rabbit hole to "functional objects"

Slide 49

Slide 49 text

thing.do(some,stuff) => behavior From "Oops! OOP's not what I thought"

Slide 50

Slide 50 text

to: thing subject: pretty please? :D message: "do", some, stuff From "Oops! OOP's not what I thought"

Slide 51

Slide 51 text

recipient message thing.do(some,stuff) From "Oops! OOP's not what I thought"

Slide 52

Slide 52 text

recipient message thing.do(some,stuff) method name arguments From "Oops! OOP's not what I thought"

Slide 53

Slide 53 text

recipient message thing('do',some,stuff) method name arguments From "Oops! OOP's not what I thought"

Slide 54

Slide 54 text

recipient message thing('do')(some)(stuff) method name arguments From "Oops! OOP's not what I thought"

Slide 55

Slide 55 text

Smalltalk (OOP) class True ifTrue: a ifFalse: b ^ a value class False ifTrue: a ifFalse: b ^ b value Lambda calculus (FP) TRUE := λx.λy.x FALSE := λx.λy.y See also: gist.github.com/vakila -> LilLambda.ipynb

Slide 56

Slide 56 text

Let’s do it! github.com/vakila/functional-workshop/ tree/master/closure

Slide 57

Slide 57 text

It's functions all the way down program === function(s)

Slide 58

Slide 58 text

Flow data through functions outputs become inputs become outputs

Slide 59

Slide 59 text

Composing functions: 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 60

Slide 60 text

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

Slide 61

Slide 61 text

Let’s do it! github.com/vakila/functional-workshop/ tree/master/composition

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Mutation (dangerous!): let cities = ["Delhi", "Bombay", "Bangalore"]; cities[1] = "Mumbai"; cities; // ["Delhi", "Bombay", "Bangalore"]

Slide 64

Slide 64 text

No mutation (safer!): const cities = ["Delhi", "Bombay", "Bangalore"]; const newCities = cities.map((city) => { if (city === "Bombay") { return "Mumbai"; } else { return city; } }); newCities;//["Delhi", "Mumbai", "Bangalore"] cities; //["Delhi", "Bombay", "Bangalore"]

Slide 65

Slide 65 text

0 1 2 3 4 5 6 7 foo Mutable data

Slide 66

Slide 66 text

8 1 2 3 4 5 6 7 foo Mutable data

Slide 67

Slide 67 text

0 1 2 3 4 5 6 7 foo Immutable data

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

Use persistent data structures for efficient immutability See also: "Immutable Data Structures for Functional JS"

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 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 76

Slide 76 text

Let’s do it! github.com/vakila/functional-workshop/ tree/master/immutability

Slide 77

Slide 77 text

Recap - What key ideas will help you "think functionally"? - When is FP the right fit? - What concepts are you eager to look into next?

Slide 78

Slide 78 text

Further reading: github.com/vakila/functional-workshop#references--further-reading Functional libraries/languages to try: github.com/vakila/functional-workshop#libraries--languages-to-try

Slide 79

Slide 79 text

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