Functional Programming

It ain't scary :)

Created by Breno Ferreira / @breno_ferreira

PhD in Math

Do I need one?

No!

Of course not!

People think it's scary

Because of this:

  • Functor
  • Monoids
  • Catamorphism
  • Monads

I'll tell you what IS scary!

Object Oriented Programming

  • Inheritance
  • Method Polimorphism
  • SOLID (SRP, OCP, LSP, ISP, DIP)
  • MVC
  • ORM
  • ...

Functional Programming is unfamiliar

  • Functor
  • Monoids
  • Catamorphism
  • Monads
  • Mappables
  • Composables
  • Aggregatables
  • Chainable

OK, but WHY!?

For that simple pleasure of being a superior programmer, and look down at normal developers in their caves banging their heads together with their for loops and mutable state just to create fire.

It will blow your mind!

Mind blown

It's also really good for

  • Data manipulation
  • Async computations
  • Concurrency
  • Code expressiveness
  • It's fun!(ctional)

So, let's see some code!

Functional Programming is all about functions


var inc = function(x) {
	return x + 1;
}
						

Referential Transparency

An expression is said to be referentially transparent if it can be replaced with its value without changing the behavior of a program (in other words, yielding a program that has the same effects and output on the same input).

Wikipedia

That means no side-effects!


var swap = function(ref x, ref y) {
	var aux = x;
	x = y;
	y = x;
}
						

Obs: pseudo-code

No side-effects!


var swap = function(x, y) {
	return [y, x];
}
						

So:

Try to avoid this!


function f(obj){
	obj.prop = "some different value";
}
						

Prefer immutability!

Don't EVER do this!


function f(obj){
	var newFunction = function(){
		....
	};

	obj.prototype.someFunction = newFunction;
}
						

Do I need to say why?

Don't do this everywhere!


document.whatever();
$('element').whatever();
var ajax = new XMLHttpRequest();
console.log();
						

They are all undesirable side-effects!

Use when appropriate, in the right places!

Recursion

In order to understand recursion, one must first understand recursion.

Basic recursion


function factorial(n){
	if(n === 0 || n === 1) return 1;
	else return n * factorial(n-1);
}
					

Tail calls


function factorial(n){
	var factImpl = function(x, result){
		if(x === 0 || x === 1) return result;
		else return factImpl(x-1, result * x);
	};

	return factImpl(n, 1);
}
					

In ES6 Harmony

Higher Order functions

Tzu-li and Tzu-ssu wereboasting about the size of their latest programs.
‘Two-hundred thousand lines,’ said Tzu-li, ‘not counting comments!’
Tzu-ssu responded, ‘Pssh, mine is almost a million lines already.’
Master Yuan-Ma said, ‘My best program has five hundred lines.’
Hearing this, Tzu-li and Tzu-ssu were enlightened.

Master Yuan-Ma, The Book of Programming

Understanding function notation

What does this mean?

f : A → B

That means: f is a function that takes a value of type A, and returns a value of type B

Example:

f : Number → String


function toString(n){
	return n.toString();
}

toString(1);
					

And this? What does this mean?

f : (A → B) → B

Back to Higher Order functions

Array functions

  • map
  • reduce
  • filter

Map

map: (Array<A>, (A → B)) → Array<B>

Which is better?


var array = [1,2,3,4,5];
var result = [];
for(var i = 0; i < array.length; i++){
	var n = array[i];
	result.push(n * 2);
}
return result;
					

var array = [1,2,3,4,5];
array.map(function(n){ return n * 2; });
					

filter

filter: (Array<A>, (A → Boolean)) → Array<A>

Which is better?


var array = [1,2,3,4,5];
var result = [];
for(var i = 0; i < array.length; i++){
	var n = array[i];
	if(n % 2 === 0){
		result.push(n);
	}
}
return result;
					

var array = [1,2,3,4,5];
array.filter(function(n){ return n % 2 === 0; });
					

reduce

reduce: (Array<A>, (A, B) → B, init:B) → B

Which is better?


var array = [1,2,3,4,5];
var result = 1;
for(var i = 0; i < array.length; i++){
	var n = array[i];
	result *= n;
}
return result;
					

var array = [1,2,3,4,5];
array.reduce(function(n, acc){ return n * acc; }, 1);
					

Practical Example


var sort = function(array){
	if(array.length === 0 || array.length === 1) return array;
	var head = array[0];
	var tail = array.slice(1);

	var smaller = sort(tail.filter(function(n){ return n <= head;}));
	var bigger = sort(tail.filter(function(n){ return n > head;}));

	return smaller.concat(head).concat(bigger);
}
					

Libs with much more

Libs with Immutable Data Structures

To learn more

Introduction to Functional Programming

Edx

October 2014

Functional Programming Principles in Scala

Coursera

TBA

Structure and Interpretation of Computer Programs

SICP

Available for free online

Q&A

Thank you!

http://brenoferreira.github.io/TDC14-JS
@breno_ferreira