Functional JavaScript. Wut?

In which I expound on things that are interesting to me.


Garrett Dawson

@killtheliterate

What Is Functional Programming?

It is a programming style that "...produces abstraction through clever ways of combining functions" [1]

What Is Functional Programming?

How is abstraction produced using this style of programming?

By Leveraging first class functions and higher-order functions

...also, by pretty much hating global state

To Functionally Program, You Need A Functional Language

  • FP needs to be facilitated by language features
  • Some languages are strictly functional - Haskell
  • Some languages are functional without strict enforcement - Scala

First Class Functions

First class functions are values, and can be used in every way that typical expressions can

First Class Functions

Can be assigned to variables

          
            var foo = function() {return 'hai'};

            foo(); // "hai"
          
        

First Class Functions

Can be returned by functions

          
            var bar = function() {
              return function() {return 'hai'};
            };

            bar(); // function () {return 'hai'}
          
        

First Class Functions

Can be passed as arguments to other functions

          
            var baz = function(func) {
              return func();
            };

            baz(function() {return 'hai'}) // "hai"
          
        

Higher-Order Functions

Use functions as its parameters and/or return a function

          
            var bar = function(func) {
              return function() {
                return func();
              };
            };

            bar(function() {return 'hai'})() // "hai"
          
        

Why Functionally Program with JavaScript?

FP is a Language Feature

  • JS has first class functions (and anonymous function expressions)
  • JS has higher-order functions
  • JS has closures (we'll talk about this later)

Functional JS Makes Your Programs Better

  • Encourages small units of code
  • Is easier to reason about
  • Is DRY (do not repeat yourself)

FP Concepts Transfers To Other Languages

it's a style, not a syntax

  • Haskell
  • Erlang
  • Scala
  • Clojure
  • Uh... math

Alright, Okay, Alright

How, functional JavaScript?

First, A Review

We know:

  • What function expressions are
  • What higher-order functions are

Stateless functions

Stateful functions mutate state outside of their scope. FP avoids mutation.

          
            var number = 1; // This is NOT functional programming

            var increment = function() {
                return number += 1;
            };

            increment(); // 2
            increment(); // 3
            increment(); // 4
          

          * Stephen Young [2]
        

Stateless Functions

Stateless functions don't mutate state outside their scope

          
            var number = 1;

            var increment = function(n) {
                return n + 1;
            };

            increment(number); // 2
            increment(number); // 2
            increment(number); // 2
          

          * Stephen Young [2]
        

Use Recursion For Looping

To understand recursion, you must understand recursion.

*Anonymous

Use Recursion For Looping

Functions that call themselves

          
            var loop = function(n) {
                if (n > 9) {
                    console.log(n);
                    return;
                } else {
                    console.log(n);
                    loop(n + 1);
                }
            };

            loop(0);
          

          * Stephen Young [2]
        

Use Array.prototype#Methods

Applicative programming is a technique that allows a function to be applied to each element of a list

*Mary Simoni [3]

Use Array.prototype#Methods

Array.prototype.map()

          
            var squared = [1, 2, 3, 4, 5].map(function(el) {
              return Math.pow(el, 2);
            }); // [1, 4, 9, 16, 25]
          
        

Use Array.prototype#Methods

Array.prototype.filter()

          
            var even = [1, 2, 3, 4, 5].filter(function(el) {
              return el % 2 === 0;
            }); // [2, 4]
          
        

Use Array.prototype#Methods

Array.prototype.reduce()

          
            var sum = [1, 2, 3, 4, 5].reduce(function(memo, curr) {
              return memo + curr;
            }); // 15
          
        

Build Predicate Functions

A predicate determines whether or not something is true or false.

Build Predicate Functions

          
            var isNull = function(obj) {
                return obj === null;
            };

            isNull(null) // true
          
        

Use Closures

Closures are functions that refer to independent (free) variables... the function defined in the closure "remembers" the environment in which it was created.

*Person that wrote the MDN page[5]

Use Closures

          
            function stringCount(string) {
              return function(subString) {
                return string.match(new RegExp(subString, 'g')).length;
              };
            }

            var count = stringCount('sup sup sup');

            count('sup'); // 3
          
        

Build Curried Functions

Currying is the act of taking a function that takes more than one argument and converting it to an equivalent function taking one argument.

*Reginald Braithwaite [3]

Build Curried Functions

          
            var foo = function (x) {
               return function (y) {
                 return function (z) {
                   return x + y + z;
                 }
               }
             }

             var bar = foo(1) // partially applied function
             bar(2)(3) // 6
          
        

Compose Functions With Functions

It’s really that simple: Whenever you are chaining two or more functions together, you’re composing them

*Reginald Braithwaite [4]

Compose Functions With Functions

          
            var compose = function(a, b) {
              return function (c) {
                return a(b(c));
              };
            };

            var addOne = function(number) { return number + 1 };
            var double = function(number) { return number * 2 };
            var addOneAndDouble = compose(double, addOne); // right to left

            addOneAndDouble(2); // 6
          
        

ez Mode

(AKA Easy Mode)

Underscore/Lo-Dash

          
            var numbers = _.filter([1, 'foo', 3, 'bar', 5, 6], _.isNumber); // [1, 3, 5, 6]

            var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) {
              return num % 2 == 0;
            }); // [2, 4, 6]
          
        

Ramda

          
            var evens = ramda.filter(function(num){ return num % 2 === 0; });
            evens([1, 2, 3, 4, 5, 6]); // [2, 4, 6]
          
        

And More Things

There is a lot to know about FP

  • Functors
  • Monads! (value burritos, mmm)
  • Promises (an monad)
  • Combinators

Go forth and write better JavaScript.