_ _ _ ___ _ _ _ _ /_\ | |_ __ ___ __| |_ / _ \| |__ ___ ___| |___| |_ ___ _ _ ___| |_ / _ \| | ' \/ _ (_-< _| (_) | '_ (_-</ _ \ / -_) _/ -_)_| ' \/ -_) _| /_/ \_\_|_|_|_\___/__/\__|\___/|_.__/__/\___/_\___|\__\___(_)_||_\___|\__|
Functional JavaScript
(and some Underscore.JS too)

Thomas Parslow

tom@almostobsolete.net
@almostobsolete
http://almostobsolete.net

Audience Participation

Your talk needs you! To tweet sentences beginning with 'functional programming is'

Functional programming is awesome.

Functional programming is a duck billed platypus

Coming up!

Why use a Functional style in JavaScript?

JavaScript is Functional: Functions are First Class

function hello(talker) {
  talker("Hello world");
}
function talk(text) {
  output(text);
}
function shout(text) {
  output(text.toUpperCase());
}
hello(talk);
hello(shout);
          

JavaScript is Functional: Anonymous Functions

function hello(talker) {
  talker("Hello world");
}

hello(function (text) {
  output('I am an anonymous function and I say: ' + text);
});
          

JavaScript is Functional: Functions are Closures

function counter() {
  var count = 0;
  return function () {
    return count++
  };
}

var a = counter(), b = counter();
output('a()=', a());
output('a()=', a());
output('b()=', b());
          

Underscore.JS

Map

var animals = ['llama','alpaca','lemming']
function makeSentence(a) {
  return a[0].toUpperCase() + a.slice(1) + ' is a type of animal';
} 
Imperative:
var results = [];
for(var i = 0; i < animals.length; i++) {
  var animal = animals[i];
  results.push(makeSentence(animal));
} 
Functional:
var results = _.map(animals, makeSentence); 
output('Map results: ',results); 

Filter

var animals = ['llama','alpaca','lemming']
function startsWithL(a) {
  return a[0] === 'l';
} 
Imperative:
var results = [];
for(var i = 0; i < animals.length; i++) {
  var animal = animals[i];
  if (startsWithL(animal)) {
    results.push(animal);
  }
} 
Functional:
results = _.filter(animals, startsWithL);
output('Filter output:', results);

Reduce

var animals = ['llama','alpaca','lemming']
function addLength(length,string) {
  return length+string.length;
} 
Imperative:
var result = 0;
for(var i = 0; i < animals.length; i++) {
  var s = animals[i];
  result = addLength(result, s);
} 
Functional:
result = _.reduce(animals, addLength, 0);
output('Reduce output:', result);

Zip

var animals = ['llama','alpaca','lemming'];
var names = ['larry','al','lem']; 
Imperative:
var results = [];
for(var i = 0; i < animals.length; i++) {
  var animal = animals[i], name = names[i];
  results.push([animal, name]);
} 
Functional:
results = _.zip(animals, names);
output('Zip output:', results);

Zip and Map together

var animals = ['llama','alpaca','lemming'];
var names = ['larry','al','lem'];
function nameAnimal(pair) {
  return pair[0] + ' the ' + pair[1];
} 
Imperative:
var results = [];
for(var i = 0; i < animals.length; i++) {
  var name = names[i], animal = animals[i];
  results.push(nameAnimal([name, animal]));
} 
Functional:
results = _.map(_.zip(names, animals), nameAnimal);
output('Zip and map:', results);

Compact, Flatten, Pluck and Uniq (phew!)

Example: Twitter

var query = prompt('Sentence start?',
                   'Functional programming is');
var url = 'http://search.twitter.com/search.json?q="' + query +
          '"&callback=?&rpp=100';
function extractSentence(tweet) {
  return tweet.match(new RegExp(query + "[a-zA-Z, :)(#']+",'ig'));
}
$.getJSON(url, function (data) {
  var tweets = _.pluck(data.results,'text');
  var sentences = _.uniq(_.flatten(
                     _.compact(_.map(tweets, extractSentence))));
  output(sentences.join('. '));
}); 

Thanks For Listening!





Any questions?


http://almostobsolete.net/talks/functionaljs/



Thomas Parslow
tom@almostobsolete.net
@almostobsolete
http://almostobsolete.net