Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Programming with JavaScript

Functional Programming with JavaScript

A quick introduction to Functional Programming using JavaScript.

Debjit Biswas

August 08, 2015
Tweet

Other Decks in Programming

Transcript

  1. <web/F> <web/F> Agenda 1. What a. are functions? b. is

    functional programming? 2. How? 3. Why? 4. Cool Stuff
  2. <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.
  3. <web/F> <web/F> Functional Programming is about using functions as units

    of abstraction and composing them to build a system.
  4. <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]); }
  5. <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.
  6. <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]
  7. <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]
  8. <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
  9. <web/F> <web/F> Map, Reduce and Filter are low-level. There are

    many others provided by libraries, which can be a better fit.
  10. <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]
  11. <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
  12. <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.
  13. <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
  14. <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);
  15. <web/F> <web/F> Example // notDone :: Object -> Boolean var

    notDone = function (todo) { return !todo.done; } var notDone = R.compose(R.not, R.prop('done'));
  16. <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
  17. <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.
  18. <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); ... }
  19. <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
  20. <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.
  21. <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?
  22. <web/F> <web/F> Partial Application // propEq :: k -> v

    -> {k: v} -> Boolean var idEqZero = R.propEq('id', 0); in this example we say that R.propEq has been partially applied.
  23. <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.
  24. <web/F> <web/F> • Declarative • Easy to reason about •

    Easy to test Why Functional Programming Matters (by John Hughes)
  25. <web/F> <web/F> Functional null checking if (x !== null &&

    x !== undefined) { f(x); } Maybe(x).map(f); //=> Maybe(f(x))
  26. <web/F> <web/F> Functional null checking if (x !== null &&

    x !== undefined) { f(x); } R.map(f, Maybe(x)); //=> Maybe(f(x))
  27. <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
  28. <web/F> <web/F> Functional null checking if (x !== null &&

    x !== undefined) { f(x); } R.map(f, Maybe(x)); //=> Maybe(f(x))
  29. <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]
  30. <web/F> <web/F> Functor is something that implements map. Some Functors

    are Array, Maybe, Either, Future and many others.
  31. <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!