4. <web/F><web/F>
Functions
A 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.
11. <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]);
}
13. <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.
14. <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]
15. <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]
16. <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
17. <web/F><web/F>
Map, Reduce and Filter are low-level. There
are many others provided by libraries, which
can be a better fit.
18. <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}] -> v
R.pluck('a', [{a: 1}, {a: 2}]); //=> [1, 2]
19. <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
20. <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.
21. <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
23. <web/F><web/F>
Example
// notDone :: Object -> Boolean
var notDone = function (todo) {
return !todo.done;
}
var notDone =
R.compose(R.not, R.prop('done'));
24. <web/F><web/F>
// wordCount :: String -> Number
var wordCount = function (s) {
return s.split(' ').length;
}
var wordCount = R.compose(
R.length, R.split(' ')
);
wordCount('How many words?') //=> 3
25. <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.
26. <web/F><web/F>
Example: Pass function
function createBuiltFile (packageName, minifier, extension, files) {
...
var name = packageName + '.' + md5(content) + '.' + extension;
...
}
function createBuiltFile (minifier, nameGenerator, files) {
...
var name = nameGenerator(content);
...
}
30. <web/F><web/F>
// add :: Number -> Number -> Number
var add = R.curry(function (x, y) {
return x + y;
});
// addOne :: Number -> Number
var addOne = add(1); addOne(5); //=> 6
A curried function can be easily specialized for
your own needs.
33. <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.
39. <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
46. <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!