hardcore functional programming

Post on 15-Jan-2015

369 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Hardcore functional programming

in JavascriptLeonardo Garcia Crespo@leogcrespogh/leoasis

Agenda

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

Currying

Currying:

f(x, y, z) = r

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

function add(a) {

return function(b) {

return a + b;

};

}

var add1 = add(1);

add1(3); // 4

function makeFullName(first) {

return function(middle) {

return function(last) {

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

};

};

}

var makeJerry = makeFullName('Jerry');

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

var add1 = add(1);

add1(2); // 3

add(1)(2); // 3

add(1, 2); // ?

_.curry(fn)

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

return a + b;

});

var add1 = add(1);

add1(2); // 3

add(1)(2); // 3

add(1, 2); // 3

Partial Application

var add1 = add(1);

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

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

Function Composition

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

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

_.compose(reverse, toUpper)

_.compose(reverse, toUpper)

"Hello"

_.compose(reverse, toUpper)

"Hello"

_.compose(reverse, toUpper)

"HELLO"

_.compose(reverse, toUpper)

"HELLO"

_.compose(reverse, toUpper)

"HELLO"

_.compose(reverse, toUpper)

"OLLEH"

_.compose(reverse, toUpper)

"OLLEH"

_.compose(reverse, toUpper)

"OLLEH"

Problem with _

Data comes first:

_.map(list, fn)

_.reduce(list, fn)

_.pluck(list, prop)

...

If data came last:

var add1ToAll = _.map(add1);

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

Examples

Fantasy Land

Functor

Semigroup

Monoid

Apply

Chain

Applicative

Monad

Map for lists:

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

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

Functors

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

where F is a functor

Laws

Identity:

map(id, F a) == F a

map(id) == id

Composition:

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

Maybe Functor

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

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

Promise Functor

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

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

Examples

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

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))

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);

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)

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);

Examples

Next

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

Why?

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

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

Thanks!

Qs?

Leonardo Garcia Crespo@leogcrespogh/leoasis

top related