Upload
webf
View
48
Download
2
Embed Size (px)
Citation preview
<web/F><web/F>
Agenda
1. Whata. are functions?b. is functional programming?
2. How?
3. Why?
4. Cool Stuff
<web/F><web/F>
Ramda lodash-fp
<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>
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>
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>
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>
Functor is something that implements map.
Some Functors are Array, Maybe, Either, Future and many others.
<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>
References
Books
● http://functionaljavascript.com/● https://leanpub.com/javascriptallongesix/● https://github.com/DrBoolean/mostly-adequate-guide
Talks
● https://www.youtube.com/watch?v=AvgwKjTPMmM● http://scott.sauyet.com/Javascript/Talk/2014/01/FuncProgTalk/● https://www.youtube.com/watch?v=m3svKOdZijA
<web/F><web/F>
Thank You!
Debjit Biswas@debjitbis08https://in.linkedin.com/in/debjitbis08