functional programming with javascript

48
<web/F> <web/F> Functional Programming with JavaScript

Upload: webf

Post on 19-Aug-2015

49 views

Category:

Technology


2 download

TRANSCRIPT

<web/F><web/F>

Functional Programmingwith JavaScript

<web/F><web/F>

Agenda

1. Whata. are functions?b. is functional programming?

2. How?

3. Why?

4. Cool Stuff

<web/F><web/F>

FunctionsA relation f from a set A to a set B is said to be a function if every element of set A has one and only one image in set B.

<web/F><web/F>

Functional Programming is about using functions as units of abstraction and composing them to build a system.

<web/F><web/F>

Functional language or a language facilitating functional programming is one which supports first-class functions.

<web/F><web/F>

R.map(function (n) {return addOne(n);

}, list);

<web/F><web/F>

R.map(function (n) {return addOne(n);

}, list);

R.map(addOne, list);

<web/F><web/F>

$http.get('/list', function(res) {callback(res);

});

<web/F><web/F>

$http.get('/list', function(res) {callback(res);

});

$http.get('/list', callback);

<web/F><web/F>

Example: Searching a list

Declarative

var nameEquals = R.compose( R.match(new RegExp(value, 'i')), R.prop('name'));var filtered = R.filter(nameEquals, list);

Imperative

var filtered = [], i = 0, pattern = new RegExp(value, 'i');

for (i = 0; i < list.length; i += 1) { if (list[i].name.match(pattern)) filtered.push(list[i]);}

<web/F><web/F>

Higher-order functions

are first-class functions, that can take as argument or return a function.

<web/F><web/F>

Map, Reduce and Filter

are the three most important functions to work with collections.

Do not use any of these as a loop.

<web/F><web/F>

If the input and output collections are always going to be same length, you probably need map.

var double = (x) => x * 2;R.map(double, [1, 2, 3]); //=> [2, 4, 6]

<web/F><web/F>

If the output collection can have lesser or equal number of items, you probably need filter.

var isEven = (n) => n % 2 === 0;R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4]

<web/F><web/F>

You probably need reduce when the input is a collection and the output is a single value.

Reduce is also known as fold.

R.reduce(R.add, 0, [1, 2, 3]); //=> 6

<web/F><web/F>

Map, Reduce and Filter are low-level. There are many others provided by libraries, which can be a better fit.

<web/F><web/F>

Example: Given an array of objects, get only the ‘name’ property values in an array.

R.map(R.prop('a'), [{a: 1}, {a: 2}]);

// pluck :: k -> [{k: v}] -> vR.pluck('a', [{a: 1}, {a: 2}]); //=> [1, 2]

<web/F><web/F>

1. Functions should be simple. 2. They should do and focus on only one thing.3. Try writing small functions.4. Do not mix concerns

Ref: Simple Made Easy by Rich Hickey

<web/F><web/F>

Create lot of functions

Don’t be afraid to create many small functions.

Abstract whenever two functions seems to do similar things or some part of them are similar.

<web/F><web/F>

Open/closed principle

states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"

Ref: https://en.wikipedia.org/wiki/Open/closed_principle

<web/F><web/F>

Function Composition

var x' = f(x) ;var x'' = g(x'); } g(f(x));

var h = R.compose(g, f); h(x);

<web/F><web/F>

Example

// notDone :: Object -> Booleanvar notDone = function (todo) { return !todo.done;}

var notDone = R.compose(R.not, R.prop('done'));

<web/F><web/F>

// wordCount :: String -> Numbervar wordCount = function (s) {

return s.split(' ').length;}

var wordCount = R.compose(R.length, R.split(' ')

);

wordCount('How many words?') //=> 3

<web/F><web/F>

Pass and return functions

If some function accepts many parameters to perform some part of its operations try to replace with function instead.

<web/F><web/F>

Example: Pass functionfunction createBuiltFile (packageName, minifier, extension, files) { ... var name = packageName + '.' + md5(content) + '.' + extension; ...}

function createBuiltFile (minifier, nameGenerator, files) { ... var name = nameGenerator(content); ...}

<web/F><web/F>

Pass functions instead of valueswhen you want to make a function more generic.

<web/F><web/F>

Work with simple data structures such as Arrays and Objects

<web/F><web/F>

Curried Functions

A function that returns a new function until it receives all its arguments.

Originated by Moses Schönfinkel

Developed by Haskell Curry

<web/F><web/F>

// add :: Number -> Number -> Numbervar add = R.curry(function (x, y) { return x + y;});

// addOne :: Number -> Numbervar addOne = add(1); addOne(5); //=> 6

A curried function can be easily specialized for your own needs.

<web/F><web/F>

fetchFromServer() .then(JSON.parse) .then(function(data){ return data.posts }) .then(function(posts){ return posts.map(function(post){ return post.title;

}); })

fetchFromServer() .then(JSON.parse) .then(R.prop('posts')) .then(R.map(R.prop('title')))

Read: Why Curry Helps?

<web/F><web/F>

Partial Application

// propEq :: k -> v -> {k: v} -> Booleanvar idEqZero = R.propEq('id', 0);

in this example we say that R.propEq has beenpartially applied.

<web/F><web/F>

● Helps you build new functions from old one.

● Think of it as configuring a function for your needs.

● It also makes composition easier.

<web/F><web/F>

● Declarative● Easy to reason about● Easy to test

Why Functional Programming Matters (by John Hughes)

<web/F><web/F>

Cool Stuff

<web/F><web/F>

Functional null checking

if (x !== null && x !== undefined) { f(x);}

<web/F><web/F>

Functional null checking

if (x !== null && x !== undefined) { f(x);}

Maybe(x).map(f); //=> Maybe(f(x))

<web/F><web/F>

Functional null checking

if (x !== null && x !== undefined) { f(x);}

R.map(f, Maybe(x)); //=> Maybe(f(x))

<web/F><web/F>

Functional null checking

if (x !== null && x !== undefined) { f(x);}

R.map(f, Maybe(x)); //=> Maybe(f(x))

var g = R.compose(R.map(f), Maybe);g(x); //=> Maybe(f(x)) only if x != null

<web/F><web/F>

Functional null checking

if (x !== null && x !== undefined) { f(x);}

R.map(f, Maybe(x)); //=> Maybe(f(x))

<web/F><web/F>

Functional null checking

if (x !== null && x !== undefined) { f(x);}

R.map(addOne, Maybe(2)); //=> Maybe(3)

R.map(addOne, [2]) //=> [3]

<web/F><web/F>

Both Maybe and Array are Functors.

<web/F><web/F>

Functor is something that implements map.

Some Functors are Array, Maybe, Either, Future and many others.

<web/F><web/F>

Fantasy Land Specificationhttps://github.com/fantasyland/fantasy-land

<web/F><web/F>

bilby.js Folktale

ramda-fantasy

<web/F><web/F>

● Start writing more functions● Preferably pure and simple functions● Glue your functions using higher-order

functions● Use a functional library● Discover!

<web/F><web/F>

Thank You!

Debjit Biswas@debjitbis08https://in.linkedin.com/in/debjitbis08