FUNCTIONAL PROGRAMMING IN JAVASCRIPT Or, “How lambdas can change your life”
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
Recursion instead of looping function fib(n) { if (n <= 2) { return 1; } return fib(n-1) + fib(n-2); }
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 alternative var 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: functional function 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!

Functional programming in JavaScript

  • 1.
    FUNCTIONAL PROGRAMMING IN JAVASCRIPT Or, “Howlambdas can change your life”
  • 2.
    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?
  • 3.
    Two Models ofComputation  Lambda calculus: Emil Post, 1936  Turing Machine: Alan Turing, 1936-1937  Proved equivalent in computational power by Turing in 1937
  • 4.
    Turing Machine  Infinitetape  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”
  • 5.
    Imperative Languages  Assignmentsequences  Same name can be associated with several values  Fixed evaluation orders  New values can be associated with the same name through command repetition
  • 6.
    A classic imperativeloop 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; };
  • 7.
    Order is important varx = 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
  • 8.
    Lambda Calculus  Rootsin 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
  • 9.
    Functional Languages  Basedon 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
  • 10.
    Recursion instead oflooping function fib(n) { if (n <= 2) { return 1; } return fib(n-1) + fib(n-2); }
  • 11.
    Functions as first-classcitizens 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
  • 12.
    JavaScript  Developed byBrendan Eich at Mozilla  Scheme in the browser  “Lisp in C’s clothing”  Supports many programming paradigms:  Classical object-oriented  Prototype-based  Imperative  Functional
  • 13.
    Functional JavaScript  Functionsas first-class citizens  Anonymous functions  Native methods:  .map()  .reduce()  .forEach()  Event-based programming (DOM API, XmlHttpRequest)  Closures
  • 14.
    .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);
  • 15.
    .map() imperative alternative varnumbers = [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);
  • 16.
    .reduce() [0, 1, 2,3, 4].reduce( function(previousValue, currentValue, index, array) { return previousValue + currentValue; } );
  • 17.
    Event callbacks document.addEventListener('click', function(){ console.log('You clicked somewhere!'); }); var clicked = function() { console.log('You clicked somewhere!’) }; document.addEventListener('click', clicked);
  • 18.
    Closures function makeFunc() { varname = "Mozilla"; function displayName() { console.log(name); } return displayName; } var myFunc = makeFunc(); myFunc();
  • 19.
    Self-executing functions var counter= (function(){ var n = 0; return function() { console.log('Times run: ‘+(++n)); } })();
  • 20.
    99 Bottles ofBeer: 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!'); } }
  • 21.
    99 bottles ofbeer: functional function 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(); }
  • 22.
    99 bottles ofbeer: functional function song(start, end, lyricGen) { return _.reduce(_.range(start, end, -1), function(acc, n) { return acc.concat(lyricGen(n)); }, []); }
  • 23.
    10 green bottles! functiongreenBottles(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(); }
  • 24.
    Conclusions  JavaScript broughtfunctional 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!

Editor's Notes

  • #3 "Functional programming is like describing your problem to a mathematician. Imperative programming is like giving instructions to an idiot."
  • #4 Strands of work in the 1930s Post 1936: “An unsolvable problem of elementary number theory” = untyped lambda calculus. 1940, developed “simply typed lambda calculus” Turing 1936-37: “On Computable Numbers, with an Application to the Entscheidungsproblem” Turing 1937: “Computability and Lambda-Definability” Foundations of computer science
  • #5 TAPE HEAD STATE REGISTER TABLE OF INSTRUCTIONS
  • #9 Any of these can model any other A result from one system will have equivalent results on equivalent systems
  • #10 i.e. pure functional languages (JavaScript does not have this “immutability” property) MORE IDEAS TO UNDERSTAND AND EXPLAIN: “Everything is an expression” “Functions as first-class citizens”
  • #12 Functions are just values like any other, e.g. a number Lots of definitions of functional programming, but every definition agrees on one point: A FUNCTIONAL PROGRAMMING LANGUAGE IS ONE FACILITATING THE USE AND CREATION OF FIRST-CLASS FUNCTIONS Other definitions (failed by JavaScript): Static typing Pattern matching Immutability Purity
  • #13  Lots of definitions of functional programming, but every definition agrees on one point: A FUNCTIONAL PROGRAMMING LANGUAGE IS ONE FACILITATING THE USE AND CREATION OF FIRST-CLASS FUNCTIONS Other definitions (failed by JavaScript): Static typing Pattern matching Immutability Purity
  • #15 // roots is now [1, 2, 3], numbers is still [1, 4, 9]
  • #20 Provide scope Counter()
  • #21 Difficult to reuse because of the precise, implementation-specific level of detail. Loops are hard to abstract! (example?) And they create noise: the real work is being done right at the core of the loop, and a functional style allows you to extract that logic and make it independent from the loop implementation
  • #22 Generates for one verse: it is the “core” of the loop lyricsSegment(9); //=> ['9 bottles of beer on the wall', // '9 bottles of beer', // 'Take one down, pass it around', // '8 bottles of beer on the wall.']
  • #23 song(99, 0, lyricSegment);