Stephen Mizell
February 09, 2015

# The Joys of Functional Programming

The fun that can be had in functional programming, from someone who is not a functional programmer.

## Stephen Mizell

February 09, 2015

## Transcript

2. ### First, Some Caveats 1. I do not do 100% functional

programming 2. I will be showing examples in Javascript 3. I do not currently use functional reactive programming
3. ### What is Functional Programming? 1. Imperative vs. Declarative 2. Persistent

and Immutable Data 3. No Side Effects 4. Noun vs. Verb 5. First class and higher order functions 6. Recursive over iterative

Reduce

6. ### Iterative Factorial var num = 5, total = 1; if

(num !== 0) { for (i = 1; i <= num; i++) { console.log(i); total = total * i; } } console.log(total);
7. ### Recursive Factorial var num = 5; function factorial(n) { if

(n === 0) return 1; return n * factorial(n - 1); } console.log(factorial(num));
8. ### Imperative vs. Declarative Imperative you express how to do it,

declarative you express what you want done
9. ### Imperative var list = [1, 2, 3, 4, 5], total

= 0; for (i = 0; i < list.length; i++) { total += list[i]; }
10. ### Declarative (Part 1) var list = [1, 2, 3, 4,

5]; var total = list.reduce(function(result, num) { return result + num; });
11. ### Declarative (Part 2) var list = [1, 2, 3, 4,

5]; function add(a, b) { return a + b; } var total = list.reduce(add);
12. ### Declarative (Part 3) var list = [1, 2, 3, 4,

5]; function add(a, b) { return a + b; } function sum(items) { return items.reduce(add); } var total = sum(list);
13. ### Using a Functional Language Clojure (def items `(1 2 3

4 5)) (reduce + items)

15. ### Here's Some Data var players = [ { totalPoints: 2031,

games: 30 }, { totalPoints: 4268, games: 45 }, { totalPoints: 2235, games: 24 }, { totalPoints: 1221, games: 22 }, { totalPoints: 5420, games: 40 } ];
16. ### Requirements 1. Get a list of the average points for

each player 2. Get an average for all players who have played 30 or more games
17. ### Imperative var playerAverages = [], allPoints = 0, allGames =

0; for (i = 0; i < players.length; i++) { var average = players[i].totalPoints / players[i].games; playerAverages.push(average); if (players[i].games >= 30) { allPoints += players[i].totalPoints; allGames += players[i].games; } } var totalAverage = allPoints / allGames;
18. ### Declarative (Part 1) var playerAverages = players.map(function(player) { return player.totalPoints

/ player.games; }); var players30Games = players.filter(function(player) { return player.games >= 30 }); var points = players30Games.map(function(player) { return player.totalPoints; }); var games = players30Games.map(function(player) { return player.games; }); var totalPoints = sum(points), totalGames = sum(games); totalAverage = totalPoints / totalGames;
19. ### Declarative (Part 2) function pluck(items, prop) { return items.map(function(item) {

return item[prop]; }); } function average(a, b) { return a / b; } var playerAverages = players.map(function(player) { return player.totalPoints / player.games; }); var players30Games = players.filter(function(player) { return player.games >= 30 }); var totalPoints = sum(pluck(players30Games, 'totalPoints')), totalGames = sum(pluck(players30Games, 'games')); totalAverage = average(totalPoints, totalGames);
20. ### Currying Currying is the technique of translating the evaluation of

a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application). –Wikipedia

22. ### Currying (Better Example) var fullName = _.curry(function(first, middle, last) {

return [first, middle, last].join(' '); }); var johnA = fullName('John', 'A.'); var johnASmith = johnA('Smith'); // John A. Smith
23. ### Currying (From Player Data Example) // Uses a library called

Ramda var players30Games = R.filter(R.pipe(R.get('games'), R.lte(30))); var totalPoints = R.pipe(players30Games, R.pluck('totalPoints'), R.sum); totalPoints(players)
24. ### How is declarative helpful? 1. Testable, maintainable, evolvable code 2.

Writing code at a higher level of abstraction 3. Through composition, it can lead to a very powerful way of thinking (like SQL)

26. ### Persistent State 1. Values are immutable 2. A "change" in

a value returns a new value (old is never thrown away) 3. These values persist (not necessarily on disk, but throughout time) 4. Big plus: fast!
27. ### Crude Example A -> B -> C Sharing all of

A Z -> A -> B -> C Sharing tail of A Y -> B -> C
28. ### Persistence 1. Shared memory usage 2. No need to do

deep clones of objects to avoid changing state 3. Allows for immutable data 4. Allows for understanding what has changed 5. Allows for no side effects

30. ### Side Effects var x = 10; function a() { x

= 4; } console.log(x);
31. ### Side Effects var x = 10; function a() { x

= 4; } a(); console.log(x);

y = x + 10;

35. ### Why is persistence and immutability good? 1. We've probably all

spent hours chasing down bugs from side effects 2. Code that mutates data requires following steps through code to understand what it is doing 3. Mutating lots of code can be expensive
36. ### Libraries for Javascript 1. Underscore.js and Lo-Dash.js provide some functions

2. Ramda - Function-ﬁrst library 3. Mori - Immutable data structures in Javascript 4. React.js and Immutable.js 5. ClojureScript
37. ### Recap, why is this helpful? 1. Code is more declarative

2. Promotes reusability and evolvability 3. Easier to write automated tests 4. Fewer bugs

39. ### FRP There is no simple deﬁnition of this on the

internet, so here are some qualities. 1. Deal with events in a functional way 2. Create streams of events rather than event listeners 3. Free of side effects

41. ### Bacon.js function movieSearch(query) { if (query.length < 3) // show

no results for queries of length < 3 return Bacon.once([]); return Bacon.fromPromise(queryMovie(query)); } var text = \$('#input') .asEventStream('keydown') .debounce(300) .map(function(event) { return event.target.value; }) .skipDuplicates(); // Only react to latest, in case they are out of order var suggestions = text.flatMapLatest(movieSearch); text.awaiting(suggestions).onValue(function(x) { if (x) \$('#results').html('Searching...'); }); suggestions.onValue(function(results) { \$('#results').html(\$.map(results, showMovie)); });