An intro to Functional Programming in JavaScript~ (and React and/or Vue)

Fig 1.0 — Dimensions
Fig 1.1 — Some kind of inter-dimensional movement
Fig 1.3 — Waterslides with data as humans

fn(name) = (name + bold)

Fig 1.4 — The slope of the tangent is 0 at the vertex
const isBold = (name.bold === true);
const phoneNumberOfDavid = '555-123-4576';if (isBold) await call(phoneNumberOfDavid);
import FibonacciAdapter from 'some-outlet-right-now';const makeLeafOnBranch = (data) => {
const scalingFactor = 1.618;
return FibbonacciAdapter({
action: 'ADD-LEAF',
someRatio: scalingFactor,
someData: data,
});
};
const drawLeaf = data => makeLeafOnBranch(data);const drawBranch = drawLeaf => drawLeaf();drawBranch(data => drawLeaf(data));

Keep this in mind: the penalty of the wrong abstraction is worse than the penalty of no abstraction.

const d = a => (a + b + c);
function d(a) {
const startPlusCrap = a;
startPlusCrap += b; startPlusCrap += c; return startPlusCrap;
}

DATA FLOW

Functional Reactive Programming is all about thinking in data flows over time.

Fig 1.4 — Functional Reactive Programming (FRP)

Directed Acyclic Graph (DAG)

Fig 1.5 — Directed Acyclic Graph (DAG)
render(
<App />,
document.getElementById('root'),
)

Flow

The internet is a series of tubes, and so is your app.

PART ONE — THE IMPORTANT THEORIES

Patterns and Anti-patterns

Fig 2.0 — Bob Nyegers: he paints nice logic in your neighbourhood.

In JavaScript, things flow the best over time immutably and unidirectionally. Why? Because of live references and dynamic typing.

  • Objects contain data.
  • Functions instigate movement of data.
Fig 2.1 — Mousetrap Board Game
  • Notice how pushing a ball down the stairs is a one-way action as part of an event.
  • Notice how Mousetrap is a series of contraptions and a one-way system. If you ignore every point in time individually at first, you can study the system as if it were in continuous motion (ie: Calculus and deterministic transformation formulas).
  • Notice how each contraption always produces the same result unless you get violent or introduce an unexpected flow over time, like turbulence. Try putting a large fan beside the game and see what happens when you mutate the air pressure values around each contraption.

Deterministic means, “if you put in the same input, you get the same output 100% of the time.”

Live References

Fig 2.2 — Pass-by-reference vs. pass-by-value
const sandwich = {
flavour: { confirmed: 'pretty good' },
isTasty: getFlavour(sandwich.flavour),
}
Fig 2.3 — Look at this as if it were a single object that doubles as a function too

Where this becomes dangerous is real-time pass-by-reference analysis.

Immutability

Immutability can free you from trying to predict the future and recount the past. Who cares where we came from or how we got here. We care where we are going next and how we are going to get there.

const config = {
title: 'Sandwiches can produce good flavour',
author: 'Alice Bobson',
timestamp: 128364096092,
}
const renderArticle (config) => {
return (
<div>
<h1>{config.title}</h1>
<h3>{config.author}</h3>
<span>Created: {Date(config.timestamp)}</span>
</div>
)
}
renderArticle(config)
const config = {
title: 'Sandwiches can produce good flavour',
author: 'Alice Bobson',
timestamp: 128364096092,
content: 'Today, we added one key to an object, and we found that
our code was easy to test, extend, and maintain.',
}
const renderArticle (config) => {
return (
<div>
<h1>{config.title}</h1>
<h3>{config.author}</h3>
<span>Created: {Date(config.timestamp)}</span>
<div>{config.content}</div>
</div>
)
}
renderArticle(config)
  • Our function expected to be supplied everything it needed
  • We supplied our function with everything it needed
  • We stored everything in a config Object
  • The function performed an action, deterministically
  • Our pattern is very robust
  1. copy the Object to a new one,
  2. stop referring to the old Object,
  3. start using the new Object from that moment on.
const user = {
firstName: 'Alice',
lastName: 'Bobson',
}
// We just learned Alice's age. We need to add it.const userWithAge = {
...user,
age: 1337,
}
return userWithAge
const fn = x => ({ x })

Remember, the shortest, most concise possible code isn’t always the simplest to understand.

Fig 2.4 — Ronco Food Dehydrator

Garbage Collection

Fig 2.5 — Depiction of the JavaScript heap without Garbage Collection

In JavaScript, the execution context is usually a function being executed.

const garbage = () => {
// when you stop referring to me, I will be gone
return 'cool'
}
const generateGarbage = () => {
const createReference = garbage()
if (createReference === 'cool') {
// perform some work
}
// as soon as we arrive here during code execution,
// JavaScript unloads `garbage` from memory
return 'that is very cool'
}

I’ve hidden a secret puzzle in the bolded words above.

Function Composition

A deterministic function produces the same output when it is given the same input.

const ok = 33const getNumber = num => num // returns 33 if you input 33const correctAnswer = 1 + getNumber(ok) + 7console.log(correctAnswer) // returns 41
Fig 3.0 — Function composition
f(g())
  • push
  • put
  • set
  • do
  • write
  • pull
  • get
  • bring
  • collect
  • read
const locationX = 'http://www.com/profile.html'const config = {
name: getProfile('Reader McGee').name,
start: '1337.html',
end: () => next(locationX),
error: () => next('404.html'),
}
// destructuring not used in order to show correlations
const goToLocation = (config) => {
if (config.start !== '1337.html') {
return config.error()
}
return config.end()
}
goToLocation(config)
  1. Where is it going?
  2. What is being returned?
if (today === 'monday') use('multiplication')
if (today === 'friday') use('division')
  1. The function is being supplied what it needs
  2. The data being supplied is dynamic, but the operations in the function are static
  3. The data types are static. We are relying on this fact.
  4. The function returns something
const users = getNumberOfUsers()
Fig 3.1 — Gottfried Wilhelm Leibniz

My brain, Gottfried! WTF were you doing in the year 1700 AD?? Is this real life??

Fig 3.2 — Luckily, I don’t need to do this in JavaScript

Conclusion

--

--

--

I prefer to work near ES6+, node.js, microservices, Neo4j, React, React Native; I compose functions and avoid classes unless private state is desired.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adam Mackintosh

Adam Mackintosh

I prefer to work near ES6+, node.js, microservices, Neo4j, React, React Native; I compose functions and avoid classes unless private state is desired.

More from Medium

Running asynchronous redux-saga tests

ESlint, Prettier, EditorConfig and Husky For react typescript Project

Difference Between ‘for…of’ and ‘for…in’

“Flat” Promises for Reactive Code