hardcore functional programming

42
Hardcore functional programming in Javascript Leonardo Garcia Crespo @leogcrespo gh/leoasis

Upload: leonardo-crespo

Post on 15-Jan-2015

369 views

Category:

Technology


2 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Hardcore functional programming

Hardcore functional programming

in JavascriptLeonardo Garcia Crespo@leogcrespogh/leoasis

Page 2: Hardcore functional programming

Agenda

● Currying & Partial Application● Function Composition● Fantasy Land● Functors● Monads

Page 3: Hardcore functional programming

Currying

Page 4: Hardcore functional programming

Currying:

f(x, y, z) = r

f(x) -> g(y) -> h(z) => r

Page 5: Hardcore functional programming

function add(a) {

return function(b) {

return a + b;

};

}

var add1 = add(1);

add1(3); // 4

Page 6: Hardcore functional programming

function makeFullName(first) {

return function(middle) {

return function(last) {

return first + ' ' + middle + ' ' + last;

};

};

}

var makeJerry = makeFullName('Jerry');

makeJerry('Lee')('Lewis');

Page 7: Hardcore functional programming

var add1 = add(1);

add1(2); // 3

add(1)(2); // 3

add(1, 2); // ?

Page 8: Hardcore functional programming

_.curry(fn)

Page 9: Hardcore functional programming

var add = _.curry(function(a, b) {

return a + b;

});

var add1 = add(1);

add1(2); // 3

add(1)(2); // 3

add(1, 2); // 3

Page 10: Hardcore functional programming

Partial Application

Page 11: Hardcore functional programming

var add1 = add(1);

var add1 = add.bind(null, 1);

var add1 = _.partial(add, 1);

Page 12: Hardcore functional programming

Function Composition

(f . g)(x) = f(g(x))

_.compose(f, g)(x) == f(g(x))

Page 13: Hardcore functional programming

_.compose(reverse, toUpper)

Page 14: Hardcore functional programming

_.compose(reverse, toUpper)

"Hello"

Page 15: Hardcore functional programming

_.compose(reverse, toUpper)

"Hello"

Page 16: Hardcore functional programming

_.compose(reverse, toUpper)

"HELLO"

Page 17: Hardcore functional programming

_.compose(reverse, toUpper)

"HELLO"

Page 18: Hardcore functional programming

_.compose(reverse, toUpper)

"HELLO"

Page 19: Hardcore functional programming

_.compose(reverse, toUpper)

"OLLEH"

Page 20: Hardcore functional programming

_.compose(reverse, toUpper)

"OLLEH"

Page 21: Hardcore functional programming

_.compose(reverse, toUpper)

"OLLEH"

Page 22: Hardcore functional programming

Problem with _

Data comes first:

_.map(list, fn)

_.reduce(list, fn)

_.pluck(list, prop)

...

Page 23: Hardcore functional programming

If data came last:

var add1ToAll = _.map(add1);

var names = _.map(get('name'));

Page 24: Hardcore functional programming

Examples

Page 25: Hardcore functional programming

Fantasy Land

Page 26: Hardcore functional programming

Functor

Semigroup

Monoid

Apply

Chain

Applicative

Monad

Page 27: Hardcore functional programming

Map for lists:

map :: (a -> b) -> [a] -> [b]

map(add1, [1, 2, 3]) // [2, 3, 4]

Page 28: Hardcore functional programming

Functors

map :: (a -> b) -> F a -> F b

where F is a functor

Page 29: Hardcore functional programming

Laws

Identity:

map(id, F a) == F a

map(id) == id

Composition:

map(f . g) == map(f) . map(g)

Page 30: Hardcore functional programming

Maybe Functor

map(add1, Maybe(2)); // Maybe(3)

map(add1, Maybe(null)); // Maybe(null)

Page 31: Hardcore functional programming

Promise Functor

map(add1, Promise(2)); // Promise(3)

map(add1, delay(3)); // Promise(...4)

Page 32: Hardcore functional programming

Examples

Page 33: Hardcore functional programming

Monads

A functor that also has:

of :: a -> M a

flatMap :: (a -> M b) -> M a -> M b

or chain :: M a -> (a -> M b) -> M b

Page 34: Hardcore functional programming

Laws

Left Identity:

of(a).chain(f) == f(a)

Right Identity:

M(a).chain(of) == M(a)

Associativity:M(a).chain(f).chain(g) == M(a).chain(x -> f(x).chain(g))

Page 35: Hardcore functional programming

List Monad

Array.of(1); // [1]

var withNeg = function(a) { return [-a, a]; };

flatMap(withNeg, [1, 2, 3]); // [-1, 1, -2, 2, -3, 3]

[1, 2, 3].chain(withNeg);

Page 36: Hardcore functional programming

Maybe Monad

Maybe.of(1); // Maybe(1)

var getName = function(obj) { return Maybe(obj.name); };

flatMap(getName, Maybe({name: 'John'})) // Maybe('John')

Maybe({name: 'John'}).chain(getName);

flatMap(getName, Maybe({age: 20})); // Maybe(null)

Page 37: Hardcore functional programming

Promise Monad

Promise.of(1); // Promise(1)

// findTodo :: Number -> Promise(todo)

var findTodo = function(id) {

return fetchFromDb('todo', id);

};

flatMap(findTodo, Promise.of(123)); // Promise(...todo)

Promise.of(123).chain(getName);

Page 38: Hardcore functional programming

Examples

Page 39: Hardcore functional programming

Next

● Monoids● Applicative Functors● Learn a FP language!● A LOT more than this

Page 40: Hardcore functional programming

Why?

● Declarative (what vs how)● Common Patterns● Small functions● Oriented to fns, not data● Correctness (mathematics)

Page 41: Hardcore functional programming

Resources

● http://learnyouahaskell.com/● Hey Underscore! You're Doing it wrong (https:

//www.youtube.com/watch?v=m3svKOdZijA)● https://github.com/fantasyland/fantasy-land● http://functionaltalks.org● Brian McKenna (@puffnfresh) & Brian Lonsdorf

(@drboolean) on Twitter

Page 42: Hardcore functional programming

Thanks!

Qs?

Leonardo Garcia Crespo@leogcrespogh/leoasis