How to JavaScript

The Functional Way

By Aleksandrs Ulme

What is Functional?

  • Math
  • Lambda calculus
  • Functions in math definition of the word
OMG WTF cat was supposed to be here, but sadly it's not :(

It's just this

Representation of function as a black box. So sorry you can't see it, it's a nice box

Reminds you of something?

  • JSON -> f -> some other JSON
  • Risk data -> f -> risk
  • API, user input -> f -> DOM state

What do we need?

  • Purity
  • Immutability
  • Functional composition

Purity

Avoid side effects
            
var c = 0;
const addTwoNumbers= (a, b) => {
  alert('explosions!');
  return a + b + c++;
}

addTwoNumbers(2, 2); // explosions!, 4, c <- 1
addTwoNumbers(2, 2); // explosions!, 5, c <- 2
            
          
            
const addThreeNumbers= (a, b, c) => {
  return a + b + c;
}

addThreeNumbers(2, 2, 0); // 4
addThreeNumbers(2, 2, 1); // 5
            
          

Immutability

Avoid mutations
            
const accounts = [100, 200, 300];

const addInterest = accounts => {
  for (i = 0; i < accounts.length; i++) {
    accounts[i] *= 1.03;
  }
}

addInterest(accounts); // accounts <- [103, 206, 309]
            
          
            
const accounts = [100, 200, 300];

const addInterest = accounts => accounts.map(acc => acc * 1.03);

const updatedAccounts = addInterest(accounts); // [103, 206, 309]
            
          

Functional composition

Use Functions as an abstraction
            
const accountsHKD = [100, 200, 300];

const withInterest = R.multiply(1.03);
const afterFees = x => x - 0.05 * x;

const settled = R.pipe(withInterest, afterFees);

const newAccountsHKD = R.map(settled, accountsHKD);
// [97.85, 195.7, 293.55]


            
          

We're already there, sorta


dr Evil tells you how to functional JavaScript

Promisses are pipes

expressed over time
            
  const user = { accountsUSD: [10, 5, 20] };

  const getAccounts = R.prop('accountsUSD');
  const USDToHKD = R.multiply(7.77);

  const accountsInHKD = Promise.resolve(user)
    .then(getAccounts)
    .then(R.map(USDToHKD));

  const totalHKD = accountsInHKD.then(R.sum); // ~272

            
        

And streams are lists

also over time
            
  const prices = highland([10, 11, 15, 12, 13, 11]);

  const mean = prices => R.sum(prices) / R.length(prices);

  prices
    .batch(3)
    .map(mean)
    .pipe(writeToSomeDb);
            
          

Two of Three Principles of Redux

  • “ State is read-only”
  • “Changes are made with pure functions”

Why bother?

Pure is awesome

  • Truly self-contained
  • Easy to reason about
  • Very unit testable

Promisses

            
              stockDataPromise
                .then(R.splitEvery(3))
                .then(R.map(mean))
                .then(R.map(toHKD))
                .then(persist);
            
          

Synergy

Fusion!

Questions?

THE END

Now go and make stuff functional