Functional Programming
How I learned to stop worrying and love the monad
WHAT
Composition & Reusable functions
passing around class-objects with hidden state in for loops
Not
WHAT
Pure Functions
someObject.property1 = "hej"
const months = ['Jan', 'March'];
months.splice(1, 0, 'Feb');
console.log(months);
Array(3) [ "Jan", "Feb", "March"]
- Side effects
WHAT
Pure Functions
- Side effects
- Deterministic
function add(first, second) {
first + second
}
WHAT
Pure Functions
- Side effects
- Deterministic
WHAT
Immutability
Thou shalt not mutate
Performance losses? Don't worry about it
WHAT
Higher order functions

WHAT
Higher order functions
- A function that takes another function as argument
- .map(), reduce(), filter()
WHY (and why not)
WHY
Parallelization
WHY
Parallelization

WHY
Composition
WHY
Composition
Frame
|> Put on wheels
|> Put on windows
|> Put on doors
|> Put on color
WHY
Testability
WHY
Why not
-
⠀
WHY
Why not
*Cricket Noise*
WHY
- Parallelization
- Tests
- Composability
HOW
HOW
React
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(prevCount => prevCount + 1);
}
return (
<button onClick={handleClick}>
You pressed me {count} times
</button>
);
}
HOW
React
What is useEffect?
HOW
Kubernetes
You set constraints
Kubernetes helps you fullfil them
HOW
More examples
HOW
function mailPreferences(arr) {
let result = [];
for (let index = 0; index < arr.length; index++) {
const person = arr[index];
if (person.age >= 18) {
person.drink = "beer";
result.push(person);
}
}
if (result) {
sendMail(result);
} else {
console.log("nothing to send");
}
}
HOW
function mailPreferencesFunc(arr) {
res = arr
.filter(({ age }) => age > 18)
.map((e) => {
e.drink = "beer";
return e;
});
if (res) {
sendMail(res);
} else {
console.log("nothing to send");
}
}
HOW
function mailPreferencesFunc(arr) {
res = arr
.filter(({ age }) => age > 18)
.map((e) =>
Object.assign({
drink: "beer",
e,
})
);
if (res) {
sendMail(res);
} else {
console.log("nothing to send");
}
}
function mailPreferences(arr) {
let result = [];
for (let index = 0; index < arr.length; index++) {
const person = arr[index];
if (person.age >= 18) {
person.drink = "beer";
result.push(person);
}
}
if (result) {
sendMail(result);
} else {
console.log("nothing to send");
}
}
HOW
function mailPreferencesFunc(arr) {
res = arr
.filter(({ age }) => age > 18)
.map((e) =>
if (e.age >= 20) {
return Object.assign({
drink: "wine",
e,
});
} else {
return Object.assign({
drink: "beer",
e,
});
}
);
if (res) {
sendMail(res);
} else {
console.log("nothing to send");
}
}
function mailPreferences(arr) {
let result = [];
for (let index = 0; index < arr.length; index++) {
const person = arr[index];
if (person.age >= 20) {
person.drink = "wine";
result.push(person);
} else if (person.age >= 18) {
person.drink = "beer";
result.push(person);
}
}
if (result) {
sendMail(result);
} else {
console.log("nothing to send");
}
}
HOW
function mailPreferences(arr) {
let result = [];
const drinkers = {
kombucha: 0,
wine: 0,
beer: 0,
};
for (let index = 0; index < arr.length; index++) {
const person = arr[index];
if (person.age >= 40) {
const drink = "kombucha";
person.drink = drink;
result.push(person);
drinkers[drink] += 1;
} else if (person.age >= 20) {
const drink = "wine";
// Same thing as above
} else if (person.age >= 18) {
const drink = "beer";
// Same thing
}
}
for (const drink in drinkers) {
const nrOfDrinkers = drinkers[drink];
if (nrOfDrinkers > 0) {
console.log(
`${drink}Drinkers ${toPercentage(nrOfDrinkers, arr.length)} %`
);
}
}
console.log(
`excluded ${toPercentage(arr.length - result.length, arr.length)} %`
);
sendMail(result);
}
HOW
function mailPreferencesFunc(arr) {
const drinkPreferences = getDrinkPreferences(arr)
const printDrinkerStats = (list, totalNr) =>
Object.entries(
list
.map(({ drink }) => drink)
.reduce((acc, drink) => {
if (!acc[drink]) {
acc[drink] = 1;
} else {
acc[drink] = acc[drink] + 1;
}
return acc;
}, {})
)
.map(([drink, drinkers]) => [drink, toPercentage(drinkers, totalNr)])
.map(([drink, percent]) => `${drink}Drinkers ${percent} %`)
.concat([`excluded ${toPercentage(totalNr - list.length, totalNr)} %`])
.map(printEntry);
printDrinkerStats(drinkPreferences, arr.length);
sendMail(drinkPreferences);
}
const getDrinkPreferences = (arr) =>
arr
.filter(({ age }) => age > 18)
.map((e) => {
if (e.age >= 40) {
return Object.assign({
drink: "kombucha",
e,
});
} else if (e.age >= 20) {
return Object.assign({
drink: "wine",
e,
});
} else if (e.age >= 18) {
return Object.assign({
drink: "beer",
e,
});
}
});
Summary
"All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor."
Summary
Its up to you!
Functional Programming
By Mikael Gråborg
Functional Programming
- 97