functional programming in javascript
TRANSCRIPT
Some basic questions
What is functional programming and how does it differ from imperative programming?
What is JavaScript? What is functional programming in
JavaScript, and how can it help me?
Two Models of Computation
Lambda calculus: Emil Post, 1936 Turing Machine: Alan Turing, 1936-1937 Proved equivalent in computational
power by Turing in 1937
Turing Machine
Infinite tape Head moves over tape, can read symbol,
change symbol, go left, or go right Modifying state in a particular order,
according to instructions “Mechanized symbol evaluation based
on assignment and time ordered evaluation”
Imperative Languages
Assignment sequences Same name can be associated with
several values Fixed evaluation orders New values can be associated with the
same name through command repetition
A classic imperative loop
function fib(n) { var a = 0, b = 1, f = 1; for (var i = 2; i <= n; i++) { f = a + b; a = b; b = f; } return f;};
Order is important
var x = 1, y = 2, buffer;buffer = x;x = y;y = buffer;// x = 2, y = 1
var x = 1, y = 2, buffer;x = y;buffer = x;y = buffer;// x = 2, y = 2
Lambda Calculus
Roots in mathematical logic and proof theory
Turing machines = Kleene’s recursive function theory = lambda calculus = generalised von Neumann machines
Attempt to describe computation in terms of computable functions
Functional Languages
Based on structured function calls: a(b(c(3)))
So what? You can nest functional calls in C! But in pure functional languages, this is the
only way to transform values: a name is only ever associated with one value
Functions as first-class citizens No assignment = no side effects Can be executed in different orders but give
the same result
Functions as first-class citizens
var arr = [42, function() { return 42; }];
var obj = {key: 42, func: function() { return 42; }}
var x = function() { return 42; };
var y = function() { return function() { return 42} };
42 + (function() { return 42; })()
//=> 84
function weirdAdd(n, f) { return n + f() }
weirdAdd(42, function() { return 42 });
//=> 84
JavaScript
Developed by Brendan Eich at Mozilla Scheme in the browser “Lisp in C’s clothing” Supports many programming paradigms:
Classical object-oriented Prototype-based Imperative Functional
Functional JavaScript
Functions as first-class citizens Anonymous functions Native methods:
.map() .reduce() .forEach()
Event-based programming (DOM API, XmlHttpRequest)
Closures
.map()
var numbers = [1, 4, 9];var roots = numbers.map(Math.sqrt);console.log(roots);var doubledRoots = roots.map( function(n) { return n * 2; });console.log(doubledRoots);
.map() imperative alternativevar numbers = [1, 4, 9];var roots = [];
for (var i=0; i<numbers.length; i++) { roots.push(Math.sqrt(numbers[i]));}
console.log(roots);
var doubledRoots = [];for (var i=0; i<roots.length; i++) { doubledRoots.push(roots[i] * 2);}
console.log(doubledRoots);
.reduce()
[0, 1, 2, 3, 4].reduce(
function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
}
);
Event callbacks
document.addEventListener('click', function() {
console.log('You clicked somewhere!');
});
var clicked = function() {
console.log('You clicked somewhere!’)
};
document.addEventListener('click', clicked);
Closures
function makeFunc() { var name = "Mozilla"; function displayName() { console.log(name); } return displayName;}
var myFunc = makeFunc();myFunc();
Self-executing functions
var counter = (function(){ var n = 0; return function() { console.log('Times run: ‘+(++n)); }})();
99 Bottles of Beer: imperative
var lyrics = [];
for (var bottles = 99; bottles > 0; bottles--) { lyrics.push(bottles + ' bottles of beer on the wall'); lyrics.push(bottles + ' bottles of beer'); lyrics.push('Take on down, pass it around');
if (bottles > 1) { lyrics.push((bottles - 1) + ' bottles of beer on the wall.'); } else { lyrics.push('No more bottles of beer on the wall!'); }}
99 bottles of beer: functionalfunction lyricSegment(n) { return _.chain([]) .push(n + ' bottles of beer on the wall') .push(n + ' bottles of beer') .push('Take one down, pass it around') .tap(function(lyrics) { if (n > 1) { lyrics.push((n - 1) + ' bottles of beer on the wall'); } else { lyrics.push('No more bottles of beer on the wall'); } }) .value();}
99 bottles of beer: functional
function song(start, end, lyricGen) { return _.reduce(_.range(start, end, -1), function(acc, n) { return acc.concat(lyricGen(n)); }, []);}
10 green bottles!
function greenBottles(n) { return _.chain([]) .push(n + ' green bottles sitting on the wall') .push(n + ' green bottles hanging on the wall') .push('And if 1 green bottle should accidentally fall') .tap(function(lyrics) { if (n > 1) { lyrics.push('There\'ll be '+ (n - 1) + ' green bottles hanging on the wall'); } else { lyrics.push('There\'ll be no more bottles hanging on the wall'); } }) .value();}
Conclusions
JavaScript brought functional programming into the mainstream
Its functional features are indispensable for event-driven programming and for general elegance
Just a glimpse of what “pure” functional languages provide (immutability, purity, algebraic data types)
But enough to make JavaScript a powerful and flexible language
Explore underscore.js!