Slide 1

Slide 1 text

Learn Functional Programming (by implementing a SQL DSL) in JavaScript and PHP @KrisJordan Tuesday, January 24, 12

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

λ Church @KrisJordan Tuesday, January 24, 12

Slide 11

Slide 11 text

(McCarthy) @KrisJordan Tuesday, January 24, 12

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

// JavaScript here

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

@KrisJordan Tuesday, January 24, 12

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Live coding. Tuesday, January 24, 12

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

Tuesday, January 24, 12

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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