Zhuoran (John) Li
A programming paradigm mapped from mathematical functions
Declarative
(what)
Imperative
(how)
vs
🥳
Given the same input, will always return the same output and produces no side effects
// Pure
const add = (a, b) => a + b
add(1, 2) // 3
add(1, 2) // 3
[1, 2, 3].slice(0, 1) // [1]
// Impure
let a = 1;
const increment = n => a += n
increment(1) // 2
increment(1) // 3
[1, 2, 3].splice(0, 1) // [1]
Math.random() // 0.8227538687335922
Math.random() // 0.6780092463695311
Using side effects is NOT forbidden!
Transforms a function with multiple arguments into a sequence/series of functions each taking a single argument.
const add = a => b => a + b
const increment = add(1)
const increment(2) // 3 === add(1)(2)
const water = cond([
[equals(0), always('water freezes at 0°C')],
[equals(100), always('water boils at 100°C')],
[T, temp => `nothing special happens at ${temp}°C`]
])
const isEligibleToVote = both(isOverEighteen, isCitizen)
const water = temperature => cond([
[val => equals(0, val), val => always('water freezes at 0°C')],
[val => equals(100, val), val => always('water boils at 100°C')],
[T, temp => `nothing special happens at ${temp}°C`]
])(temperature)
const isEligibleToVote = age =>
both(
val => isOverEighteen(val),
val => isCitizen(val)
)(age)
🥳 After
🤪 Before
h(g(f(x)))
compose(h, g, f)(x)
const toAlladin = compose(g, f)
toAlladin(aPerson)
const toAlladin = pipe(f, g)
toAlladin(aPerson)
compose: right -> left
pipe: left -> right
Identity and Associativity
// Identity
[2].map(x => x) === [2]
// Associativity
const f = x => x * 2
const g = x => x + 2
[2].map(g).map(f) === [2].map(compose(f, g)) // [8] [8]
Initial
(Not Asked)
Verifying One-time URL
(Loading)
Invalid URL
(Failure)
Valid URL
(Success)
Remote Object - Tagged Union (Sum Types)
Verifying One-time URL
Error (e.g. Invalid Reset Password URL)
Initial State
Success
Productivity plugin in Alfred
The End