The document discusses functional programming concepts like pure functions, immutable data, and avoiding side effects. It compares imperative programming constructs like loops and mutable state to functional alternatives like map, filter, reduce. It argues that a functional style enables better reasoning about programs by avoiding side effects and complex control flow. Specific examples show transforming an imperative loop into a functional map and handling asynchronous code through chained promises or futures. Overall it advocates for a functional programming approach.
18. const dotChainy = str => {
const lower = str.toLowerCase()
const words = lower.split(' ')
words.reverse()
for(let i in words) {
words[i] = words[i].trim()
}
let keepers = []
for(let i in words) {
if(words[i].length > 3) {
keepers.push(words[i])
}
}
return keepers.join('')
}
19. const dotChainy = str => {
const lower = str.toLowerCase()
const words = lower.split(' ')
words.reverse()
for(let i in words) {
words[i] = words[i].trim()
}
let keepers = []
for(let i in words) {
if(words[i].length > 3) {
keepers.push(words[i])
}
}
return keepers.join('')
}
20. class AppMailer {
constructor() {
this.emailer = new Emailer()
}
removeInvalidAddresses() {
for(let i in this.addresses) {
if(!this.addresses[i].match(/@/)) {
this.addresses.splice(i, 1)
}
}
}
sendEmail({from, to}) {
this.addresses = to
this.emailer.setSender(from)
this.removeInvalidAddresses()
this.emailer.setRecipients(this.addresses)
this.emailer.send()
}
21.
22. “the major contributor to this complexity in many systems is
the handling of state and the burden that this adds when
trying to analyse and reason about the system.”
Out of the Tar Pit 2006
-Ben Moseley & Peter Marks
34. for(let thing in things) {
if(thing.amount > 100) keepers.push(thing.name)
}
for (i = 0; i < cars.length; i++) {
text += cars[i] + "<br>";
}
while (i < 10) {
text += "The number is " + i;
i++;
}
86. Left('no ducks :(').fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
// we had an error: no ducks :(
Right('ducks').fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
//"DUCKS"
87. Left('no ducks :(').fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
// we had an error: no ducks :(
Right('ducks').fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
//"DUCKS"
88. Left('no ducks :(').fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
// we had an error: no ducks :(
Right('ducks').fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
//"DUCKS"
123. const Reducer = g =>
({
fold: g,
contramap: f =>
Reducer((acc, x) => g(acc, f(x))),
map: f =>
Reducer((acc, x) => f(g(acc, x)))
})
124. const r = Reducer((acc, x) => acc.concat(x))
.contramap(x => `The number is ${x}`)
.map(x => x + '! ')
[1,2,3].reduce(r.fold, '')
// The number is 1! The number is 2! The number is 3!
const Reducer = g =>
({
fold: g,
contramap: f =>
Reducer((acc, x) => g(acc, f(x))),
map: f =>
Reducer((acc, x) => f(g(acc, x)))
})
125. const Reducer = g =>
({
fold: g,
contramap: f =>
Reducer((acc, x) => g(acc, f(x))),
map: f =>
Reducer((acc, x) => f(g(acc, x)))
})
126. const Reducer = g =>
({
fold: g,
contramap: f =>
Reducer((acc, x) => g(acc, f(x))),
map: f =>
Reducer((acc, x) => f(g(acc, x))),
concat: o =>
Reducer((acc, x) => o.fold(g(acc, x), x))
})