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