SlideShare une entreprise Scribd logo
1  sur  143
.values()
.flatten()
.sortBy((b) =>
b.CoreRelease.dataValue
.reverse()
.value()
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
const doin_Thangs = str =>
_(str)
.words()
.groupBy(s => s.length)
.orderBy(x => x.length)
.take(2)
.flatten()
.value()
const reactiveUpInHere = el =>
fromEvent(el, 'keyup')
.map(e => e.target.value)
.filter(text => text.length > 2)
.throttle(500)
.distinctUntilChanged()
player
.unitWithinRange(2)
.where(UnitIs.Enemy)
.where(UnitIs.Tank)
.DoDamage(5)
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
Chain Dot Com '
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
‘chain dot com '
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
['chain', 'dot', 'com ']
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
['chain', 'dot', 'com']
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
['com', 'dot', 'chain']
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('')
}
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('')
}
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()
}
“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
const dotChainy = str =>
str
.toLowerCase()
.split(' ')
.map(c => c.trim())
.reverse()
.filter(x => x.length > 3)
.join('')
WHAT IF I TOLD YOU…
WHAT IF I TOLD YOU…
Programming !== Math
try {
return f(x)
} catch(e) {
console.error(e)
}
if(x) {
return f()
} else {
return y
}
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++;
}
let stuff = [1,2,3]
stuff = [1,2]
stuff.splice(0, 2)
stuff.pop()
Assignment
Loops
Callbacks
Side Effects
Branching
Errors
Programming !== Math
Programming != Math
f . g
f . g
dot
f . g = x => f(g(x))
str.toUpperCase().trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a b
f
c
g
a
g
c
f.
a
F(a)
b
f
F(f)
c
g
F(b)
F(g)
F(c)
a
F(a)
g
F(g.f)
c
f
F(c)
.
const contrivedEx1 = str => {
const trimmed = str.trim()
const number = parseInt(trimmed)
const nextNumber = number + 1
return String.fromCharCode(nextNumber)
}
contrivedEx1(' 64 ')
// 'A'
const contrivedEx1 = str =>
[str.trim()]
.map(trimmed => parseInt(trimmed))
.map(number => number + 1)
.map(nextNumber =>
String.fromCharCode(nextNumber))
const contrivedEx1 = str => {
const trimmed = str.trim()
const number = parseInt(trimmed)
const nextNumber = number + 1
return String.fromCharCode(nextNumber)
}
contrivedEx1(' 64 ')
// [‘A’]
const contrivedEx1 = str =>
[str.trim()]
.map(trimmed => new Number(trimmed))
.map(number => number + 1)
.map(nextNumber =>
String.fromCharCode(nextNumber))
const contrivedEx1 = str => {
const trimmed = str.trim()
const number = parseInt(trimmed)
const nextNumber = number + 1
return String.fromCharCode(nextNumber)
}
contrivedEx1(' 64 ')
// [‘A’]
const contrivedEx1 = str =>
[str.trim()]
.map(trimmed => new Number(trimmed))
.map(number => number + 1)
.map(nextNumber =>
String.fromCharCode(nextNumber))
const contrivedEx1 = str => {
const trimmed = str.trim()
const number = parseInt(trimmed)
const nextNumber = number + 1
return String.fromCharCode(nextNumber)
}
contrivedEx1(' 64 ')
// [‘A’]
const contrivedEx1 = str =>
Box(str.trim())
.map(trimmed => new Number(trimmed))
.map(number => number + 1)
.map(nextNumber =>
String.fromCharCode(nextNumber))
contrivedEx1(' 64 ')
// Box(‘A’)
const Box = x =>
({
map: f => Box(f(x))
})
const contrivedEx1 = str =>
Box(str.trim())
.map(trimmed => new Number(trimmed))
.map(number => number + 1)
.map(nextNumber =>
String.fromCharCode(nextNumber))
contrivedEx1(' 64 ')
// Box(‘A’)
const Box = x =>
({
map: f => Box(f(x))
})
const contrivedEx1 = str =>
Box(str.trim())
.map(trimmed => new Number(trimmed))
.map(number => number + 1)
.fold(nextNumber =>
String.fromCharCode(nextNumber))
contrivedEx1(' 64 ')
// ‘A’
const Box = x =>
({
map: f => Box(f(x)),
fold: f => f(x)
})
Unified call syntax
Minimized state
Captured Assignment
Forced Control Flow
Assignment
Loops
Callbacks
Side Effects
Branching
Errors
Loops
map
filter
reduce
const range = (i, count) =>
unfold(x => if(x <= count) [x, x+1], i)
range(5,10)
// [ 5, 6, 7, 8, 9, 10 ]
const alphabet = () =>
unfold(x => if(x < 26) [String.fromCharCode(x+65), x+1], 0)
alphabet()
// [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]
Assignment
Loops
Callbacks
Side Effects
Branching
Errors
Callbacks
Side Effects
Promise(6).then(six => six / 2)
// Promise(3)
Promise(6).then(six => Promise(six / 2))
// Promise(3)
Promise(6).map(six => six / 2)
// Promise(3)
Promise(6).chain(six => Promise(six / 2))
// Promise(3)
Promise(6).then(six => six / 2)
// Promise(3)
Promise(6).then(six => Promise(six / 2))
// Promise(3)
Promise(6).map(six => six / 2)
// Promise(3)
Promise(6).chain(six => Promise(six / 2))
// Promise(3)
Promise(6).then(six => six / 2)
// Promise(3)
Promise(6).then(six => Promise(six / 2))
// Promise(3)
Promise(6).map(six => six / 2)
// Promise(3)
Promise(6).chain(six => Promise(six / 2))
// Promise(3)
const contrivedEx2 = () =>
fs.readFile('cfg.json', 'utf-8', (err, contents) => {
if(err) throw err
const newContents = contents.replace(/8/g, '6')
fs.writeFile('cfg1.json', newContents, (err, _) => {
if(err) throw err
console.log('success!')
})
})
const readFile = futurize(fs.readFile)
const writeFile = futurize(fs.writeFile)
const contrivedEx2 = () =>
readFile('cfg.json', 'utf-8')
.map(contents => contents.replace(/8/g, '6'))
.chain(replaced => writeFile('cfg1.json', replaced))
const contrivedEx2 = () =>
fs.readFile('cfg.json', 'utf-8', (err, contents) => {
if(err) throw err
const newContents = contents.replace(/8/g, '6')
fs.writeFile('cfg1.json', newContents, (err, _) => {
if(err) throw err
console.log('success!')
})
})
const readFile = futurize(fs.readFile)
const writeFile = futurize(fs.writeFile)
const contrivedEx2 = () =>
readFile('cfg.json', 'utf-8')
.map(contents => contents.replace(/8/g, '6'))
.chain(replaced => writeFile('cfg1.json', replaced))
const readFile = futurize(fs.readFile)
const writeFile = futurize(fs.writeFile)
const contrivedEx2 = () =>
readFile('cfg.json', 'utf-8')
.map(contents => contents.replace(/8/g, '6'))
.chain(replaced => writeFile('cfg1.json', replaced))
contrivedEx2().fork(e => console.error(e),
r => console.log('success!'))
const lib = username =>
getTweets(username)
.map(ts => truncateTo130(ts))
.chain(ts => writeFile('tweets.json', ts))
lib(‘@drboolean’)
const lib = username =>
getTweets(username)
.map(ts => truncateTo130(ts))
.chain(ts => writeFile('tweets.json', ts))
lib(‘@drboolean’)
.chain(f => saveToS3(f))
const lib = username =>
getTweets(username)
.map(ts => truncateTo130(ts))
.chain(ts => writeFile('tweets.json', ts))
lib(‘@drboolean’)
.chain(f => saveToS3(f))
.fork(e => console.error(e),
r => console.log(r))
Assignment
Loops
Callbacks
Side Effects
Branching
Errors
Branching
Errors
Either/Or
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"
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"
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"
leftOrRight.fold(e => `we had an error: ${e}`,
s => s.toUpperCase())
Right({hair: 'brown'})
.map(obj => obj.hair)
.map(brown => brown.length)
.chain(five => Right(five * 2))
// Right(10)
Left('ignored')
.map(obj => obj.hair)
.map(brown => brown.length)
.chain(five => Left(five * 2))
// Left('ignored')
const getConfig = () => {
try {
return fs.readFileSync('cfg.json')
} catch(e) {
return null
}
}
const contrivedEx3 = () => {
const cfg = getConfig()
if(cfg) {
const parsed = JSON.parse(cfg)
return parsed.port
} else {
return 3000
}
}
const getConfig = () =>
Either.try(fs.readFileSync)('cfg.json')
const contrivedEx3 = () =>
getConfig()
.map(JSON.parse)
.fold(e => 3000, c => c.port)
const getConfig = () =>
Either.try(fs.readFileSync)('cfg.json')
const contrivedEx3 = () =>
getConfig()
.map(JSON.parse)
.fold(e => 3000, c => c.port)
const getConfig = () => {
try {
return fs.readFileSync('cfg.json')
} catch(e) {
return null
}
}
const contrivedEx3 = () => {
const cfg = getConfig()
if(cfg) {
const parsed = JSON.parse(cfg)
return parsed.port
} else {
return 3000
}
}
Claim
const contrivedEx4 = user => {
const address = user.address
if(address) {
const zip = address.match(/(d{5})$/i)
if(zip) {
const city = cityByZip(zip)
if(city) {
return city
} else {
return "can't find city"
}
}
}
return "can't find city"
}
const contrivedEx4 = user =>
fromNullable(user.address)
.chain(a => fromNullable(a.match(/(d{5})$/i)))
.chain(zip => fromNullable(cityByZip(zip)))
.fold(() => "can't find city", city => city)
const contrivedEx4 = user => {
const address = user.address
if(address) {
const zip = address.match(/(d{5})$/i)
if(zip) {
const city = cityByZip(zip)
if(city) {
return city
} else {
return "can't find city"
}
}
}
return "can't find city"
}
const contrivedEx4 = user =>
fromNullable(user.address)
.chain(a => fromNullable(a.match(/(d{5})$/i)))
.chain(zip => fromNullable(cityByZip(zip)))
.fold(() => "can't find city", city => city)
Assignment
Loops
Callbacks
Side Effects
Branching
Errors
const depObjs = b =>
List(b.deps).flatMap(next =>
findDependencyByProject(next.Project.name, b.previous.deps)
.fold(x => x,
found => makeArgs(next, found)))
const mapBuildsAndDepsForDiffQueue = (builds) =>
List(builds)
.filter(b => b.previous)
.flatMap(b => makeArgs(b, b.previous).concat(depObjs(b)))
.filter(b => b)
.toJS()
const filterExistingDiffs = (items) =>
List(items).traverse(Task.of, (i) =>
find(Diff, { BuildId: i.buildId, DiffId: i.prevId, type: i.method })
.map(e => e.swap().getOrElse(null))
.map(bs => bs.filter(x => x).toJS())
const buildProject = ({branch, sha}) =>
queueUnzipWwwOnS3(sha)
.chain(() => isReleaseOrMainBranch(branch))
.fold(() => _.noop,
() =>
generateReport(sha)
.chain(queueDiffsForTileBuildsAndDeps)
.chain(() =>
getHeadCommit(sha)
.fold(() => Task.of(null),
head =>
makeVrtDeployment(head, sha)
.chain(() => createPrApp(head, sha))))
.fork(console.error,
console.log))
const vrtReport = ({sha, email, platforms}) =>
rejectFinishedPlatformOptions(platforms)
.chain(plats => plats.map(gatherScreenshots))
.chain(shots =>
fromNullable(sha)
.fold(() => findLastRef(),
() => findBuild({sha}))
.chain(ref =>
renderReport(shots, ref, email)))
.fork(e => e, r => r)
Harder to hack
const getConfig = () =>
Either.try(fs.readFileSync)('cfg.json')
const contrivedEx3 = () =>
getConfig()
.map(JSON.parse)
.fold(e => 3000, c => c.port)
Safer
const ProfileLink = user =>
<a href={`/users/${u.id}`}>{u.name}</a>
const Header = str =>
<h1>Now Viewing {str}</h1>
Component :: a -> JSX
a JSX
f
a JSX
f
b
g
a JSX
f
b
g
a JSX
f
b
g
const Comp = g =>
({
fold: g,
contramap: f =>
Comp(x => g(f(x)))
})
const Comp = g =>
({
fold: g,
contramap: f =>
Comp(x => g(f(x)))
})
const Heading = str =>
<h1>Now Viewing {str}</h1>
const Title = Comp(Heading).contramap(s => s.pageName)
const Title = Comp(Heading).contramap(s => s.pageName)
Title.fold({ pageName: ‘Home',
currentUser: { id: 2, name: 'Chris Harrison’ } })
// <h1>Now Viewing Home</h1>
const Comp = g =>
({
fold: g,
contramap: f =>
Comp(x => g(f(x)))
})
const Heading = str =>
<h1>Now Viewing {str}</h1>
const Comp = g =>
({
fold: g,
contramap: f =>
Comp(x => g(f(x)))
})
const Comp = g =>
({
fold: g,
contramap: f =>
Comp(x => g(f(x))),
concat: other =>
Comp(x => <div>{g(x)} {other.fold(x)}</div>)
})
const ProfileLink = user =>
<a href={`/users/${u.id}`}>{u.name}</a>)
const Heading = str =>
<h1>Now Viewing {str}</h1>
const Heading = Comp(Title).contramap(s => s.pageName)
const Link = Comp(ProfileLink).contramap(s => s.currentUser)
const App = Heading.concat(Link)
const ProfileLink = user =>
<a href={`/users/${u.id}`}>{u.name}</a>)
const Heading = str =>
<h1>Now Viewing {str}</h1>
const Heading = Comp(Title).contramap(s => s.pageName)
const Link = Comp(ProfileLink).contramap(s => s.currentUser)
const App = Heading.concat(Link)
App.fold({ pageName: ‘Home',
currentUser: { name: 'Chris Harrison’ } })
// <div>
// <h1>Now Viewing Home</h1>
// <a href="/users/22">Chris Harrison</a>
// </div>
Reducer :: (a, b) -> a
const Reducer = g =>
({
fold: g,
contramap: f =>
Reducer((acc, x) => g(acc, f(x))),
map: f =>
Reducer((acc, x) => f(g(acc, x)))
})
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)))
})
const Reducer = g =>
({
fold: g,
contramap: f =>
Reducer((acc, x) => g(acc, f(x))),
map: f =>
Reducer((acc, x) => f(g(acc, x)))
})
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))
})
const appReducer = Reducer((state, action) => {
switch (action.type) {
case 'set_visibility_filter':
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
})
const todoReducer = Reducer((state, action) => {
switch (action.type) {
case 'new_todo':
const t = { id: 0, title: action.payload.title }
return Object.assign({}, state, {
todos: state.todos.concat(t)
})
default:
return state
}
})
const todoApp =
appReducer
.concat(todoReducer)
.contramap(action => Object.assign({filter: 'all'}, action))
.map(s => Object.assign({}, s, {lastUpdated: Date()}))
const todoApp =
appReducer
.concat(todoReducer)
.contramap(action => Object.assign({filter: 'all'}, action))
.map(s => Object.assign({}, s, {lastUpdated: Date()}))
todoApp.fold({visibilityFilter: ‘complete'},
{type: ‘set_visibility_filter'})
// { visibilityFilter: 'all',
// lastUpdated: 'Sun Aug 21 2016 11:04:48 GMT-0700 (PDT)' }
const todoApp =
appReducer
.contramap(action => Object.assign({filter: 'all'}, action))
.concat(todoReducer)
.map(s => Object.assign({}, s, {lastUpdated: Date()}))
todoApp.fold({visibilityFilter: ‘complete'},
{type: ‘set_visibility_filter'})
// { visibilityFilter: 'all',
// lastUpdated: 'Sun Aug 21 2016 11:04:48 GMT-0700 (PDT)' }
Hoc :: Component -> Component
const Hoc = g =>
({
fold: g,
concat: other =>
Hoc(x => g(other.fold(x)))
})
const hoc = Hoc(withReducer(‘state', 'dispatch', todoApp.fold, {todos: []}))
const Todos = hoc.fold(({ state, dispatch }) =>
<div>
<span>Filter: {state.visibilityFilter}</span>
<ul>
{ state.todos.map(t => <li>{t.title}</li>) }
</ul>
<button onClick={() =>
dispatch({ type: 'new_todo', payload: {title: 'New todo'}})}>
Add Todo
</button>
<button onClick={() =>
dispatch({ type: 'set_visibility_filter' })}>
Set Visibility
</button>
</div>
)
const App = Heading.contramap(s => s.pageName)
.concat(TodoComp)
.concat(Link.contramap(s => s.currentUser))
.fold({ pageName: 'Home',
currentUser: {id: 2, name: 'Boris' } })
ReactDOM.render(App, document.getElementById('body'))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s => <h1>Now Viewing {s}</h1>)
const Link = Component(u => <a href={`/users/${u.id}`}>{u.name}</a>)
https://jsfiddle.net/cnsn8yk2/9/
map =
compose =
program construction
// Functor
Box.of(20).map(x => x / 2)
// Box(10)
// Monad
Box.of(true).chain(x => Box.of(!x))
// Box(false)
// Monoid
Box.of('small').concat(Box.of('pox'))
// Box('smallpox')
// Applicative
Box.of(x => x + 1).ap(2)
// Box(3)
// Traversable
Box.of(3).traverse(Either.of, x => fromNullable(x))
// Right(Box(3))
// Natural transformation
eitherToBox(fromNullable(null))
// Box(null)
Professor Frisby’s Composable JavaScript
@drboolean
@drboolean

Contenu connexe

Tendances

Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Baruch Sadogursky
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptLoïc Knuchel
 
imager package in R and examples..
imager package in R and examples..imager package in R and examples..
imager package in R and examples..Dr. Volkan OBAN
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4Kwang Yul Seo
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)riue
 
Advanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part IIAdvanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part IIDr. Volkan OBAN
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxEleanor McHugh
 
Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...
Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...
Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...Dr. Volkan OBAN
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...PROIDEA
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogrammingRichie Cotton
 
Useful javascript
Useful javascriptUseful javascript
Useful javascriptLei Kang
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsBaruch Sadogursky
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYvikram mahendra
 
Groovy collection api
Groovy collection apiGroovy collection api
Groovy collection apitrygvea
 

Tendances (18)

Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScript
 
imager package in R and examples..
imager package in R and examples..imager package in R and examples..
imager package in R and examples..
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
 
Scala Parallel Collections
Scala Parallel CollectionsScala Parallel Collections
Scala Parallel Collections
 
Advanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part IIAdvanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part II
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Scala by Luc Duponcheel
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc Duponcheel
 
Kotlin class
Kotlin classKotlin class
Kotlin class
 
Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...
Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...
Some R Examples[R table and Graphics] -Advanced Data Visualization in R (Some...
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogramming
 
Useful javascript
Useful javascriptUseful javascript
Useful javascript
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAY
 
Groovy collection api
Groovy collection apiGroovy collection api
Groovy collection api
 

En vedette

En vedette (6)

Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Functional Reactive Programming in Javascript
Functional Reactive Programming in JavascriptFunctional Reactive Programming in Javascript
Functional Reactive Programming in Javascript
 
Functional js class
Functional js classFunctional js class
Functional js class
 
Liftin every day
Liftin every dayLiftin every day
Liftin every day
 
Js for learning
Js for learningJs for learning
Js for learning
 
Underscore
UnderscoreUnderscore
Underscore
 

Similaire à Chain Reactive Programming Concepts

Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1Ke Wei Louis
 
How are Race Conditions in single threaded JavaScript possible?
How are Race Conditions in single threaded JavaScript possible?How are Race Conditions in single threaded JavaScript possible?
How are Race Conditions in single threaded JavaScript possible?Timur Shemsedinov
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語ikdysfm
 
Prototype programming in JavaScript
Prototype programming in JavaScriptPrototype programming in JavaScript
Prototype programming in JavaScriptTimur Shemsedinov
 
Programming Languages: comparison, history, future
Programming Languages: comparison, history, futureProgramming Languages: comparison, history, future
Programming Languages: comparison, history, futureTimur Shemsedinov
 
Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...
Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...
Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...Timur Shemsedinov
 
Everything is composable
Everything is composableEverything is composable
Everything is composableVictor Igor
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and GoEleanor McHugh
 
Asynchronous programming and mutlithreading
Asynchronous programming and mutlithreadingAsynchronous programming and mutlithreading
Asynchronous programming and mutlithreadingTimur Shemsedinov
 
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...Revolution Analytics
 
Go: It's Not Just For Google
Go: It's Not Just For GoogleGo: It's Not Just For Google
Go: It's Not Just For GoogleEleanor McHugh
 
Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4Randa Elanwar
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent SevenMike Fogus
 

Similaire à Chain Reactive Programming Concepts (20)

Node.js in 2020 - part 3
Node.js in 2020 - part 3Node.js in 2020 - part 3
Node.js in 2020 - part 3
 
Patterns and antipatterns
Patterns and antipatternsPatterns and antipatterns
Patterns and antipatterns
 
Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1
 
How are Race Conditions in single threaded JavaScript possible?
How are Race Conditions in single threaded JavaScript possible?How are Race Conditions in single threaded JavaScript possible?
How are Race Conditions in single threaded JavaScript possible?
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
 
Prototype programming in JavaScript
Prototype programming in JavaScriptPrototype programming in JavaScript
Prototype programming in JavaScript
 
Programming Languages: comparison, history, future
Programming Languages: comparison, history, futureProgramming Languages: comparison, history, future
Programming Languages: comparison, history, future
 
Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...
Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...
Новое в JavaScript: ES.Next, ECMAScript 2020, ES11, ES10, ES9, ES8, ES7, ES6,...
 
CLUSTERGRAM
CLUSTERGRAMCLUSTERGRAM
CLUSTERGRAM
 
Everything is composable
Everything is composableEverything is composable
Everything is composable
 
Node.js in 2020 - part 2
Node.js in 2020 - part 2Node.js in 2020 - part 2
Node.js in 2020 - part 2
 
Monadologie
MonadologieMonadologie
Monadologie
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
 
Asynchronous programming and mutlithreading
Asynchronous programming and mutlithreadingAsynchronous programming and mutlithreading
Asynchronous programming and mutlithreading
 
Lập trình Python cơ bản
Lập trình Python cơ bảnLập trình Python cơ bản
Lập trình Python cơ bản
 
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
 
Go: It's Not Just For Google
Go: It's Not Just For GoogleGo: It's Not Just For Google
Go: It's Not Just For Google
 
Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
 
Py3k
Py3kPy3k
Py3k
 

Dernier

What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 

Dernier (20)

What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 

Chain Reactive Programming Concepts

  • 1.
  • 2.
  • 3.
  • 5.
  • 6.
  • 7. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  • 8. const doin_Thangs = str => _(str) .words() .groupBy(s => s.length) .orderBy(x => x.length) .take(2) .flatten() .value()
  • 9. const reactiveUpInHere = el => fromEvent(el, 'keyup') .map(e => e.target.value) .filter(text => text.length > 2) .throttle(500) .distinctUntilChanged()
  • 11. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  • 12. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  • 13. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') Chain Dot Com '
  • 14. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ‘chain dot com '
  • 15. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ['chain', 'dot', 'com ']
  • 16. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ['chain', 'dot', 'com']
  • 17. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ['com', 'dot', 'chain']
  • 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
  • 23.
  • 24.
  • 25. const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  • 26. WHAT IF I TOLD YOU…
  • 27.
  • 28. WHAT IF I TOLD YOU…
  • 29.
  • 30.
  • 32. try { return f(x) } catch(e) { console.error(e) }
  • 33. if(x) { return f() } else { return y }
  • 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++; }
  • 35. let stuff = [1,2,3] stuff = [1,2]
  • 40. f . g
  • 42. f . g = x => f(g(x))
  • 45. fn fn
  • 46. fnfn
  • 47.
  • 48.
  • 49.
  • 50.
  • 55. const contrivedEx1 = str => { const trimmed = str.trim() const number = parseInt(trimmed) const nextNumber = number + 1 return String.fromCharCode(nextNumber) } contrivedEx1(' 64 ') // 'A'
  • 56. const contrivedEx1 = str => [str.trim()] .map(trimmed => parseInt(trimmed)) .map(number => number + 1) .map(nextNumber => String.fromCharCode(nextNumber)) const contrivedEx1 = str => { const trimmed = str.trim() const number = parseInt(trimmed) const nextNumber = number + 1 return String.fromCharCode(nextNumber) } contrivedEx1(' 64 ') // [‘A’]
  • 57. const contrivedEx1 = str => [str.trim()] .map(trimmed => new Number(trimmed)) .map(number => number + 1) .map(nextNumber => String.fromCharCode(nextNumber)) const contrivedEx1 = str => { const trimmed = str.trim() const number = parseInt(trimmed) const nextNumber = number + 1 return String.fromCharCode(nextNumber) } contrivedEx1(' 64 ') // [‘A’]
  • 58. const contrivedEx1 = str => [str.trim()] .map(trimmed => new Number(trimmed)) .map(number => number + 1) .map(nextNumber => String.fromCharCode(nextNumber)) const contrivedEx1 = str => { const trimmed = str.trim() const number = parseInt(trimmed) const nextNumber = number + 1 return String.fromCharCode(nextNumber) } contrivedEx1(' 64 ') // [‘A’]
  • 59. const contrivedEx1 = str => Box(str.trim()) .map(trimmed => new Number(trimmed)) .map(number => number + 1) .map(nextNumber => String.fromCharCode(nextNumber)) contrivedEx1(' 64 ') // Box(‘A’) const Box = x => ({ map: f => Box(f(x)) })
  • 60. const contrivedEx1 = str => Box(str.trim()) .map(trimmed => new Number(trimmed)) .map(number => number + 1) .map(nextNumber => String.fromCharCode(nextNumber)) contrivedEx1(' 64 ') // Box(‘A’) const Box = x => ({ map: f => Box(f(x)) })
  • 61. const contrivedEx1 = str => Box(str.trim()) .map(trimmed => new Number(trimmed)) .map(number => number + 1) .fold(nextNumber => String.fromCharCode(nextNumber)) contrivedEx1(' 64 ') // ‘A’ const Box = x => ({ map: f => Box(f(x)), fold: f => f(x) })
  • 62.
  • 63.
  • 64. Unified call syntax Minimized state Captured Assignment Forced Control Flow
  • 66. Loops
  • 68. const range = (i, count) => unfold(x => if(x <= count) [x, x+1], i) range(5,10) // [ 5, 6, 7, 8, 9, 10 ]
  • 69. const alphabet = () => unfold(x => if(x < 26) [String.fromCharCode(x+65), x+1], 0) alphabet() // [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]
  • 72. Promise(6).then(six => six / 2) // Promise(3) Promise(6).then(six => Promise(six / 2)) // Promise(3) Promise(6).map(six => six / 2) // Promise(3) Promise(6).chain(six => Promise(six / 2)) // Promise(3)
  • 73. Promise(6).then(six => six / 2) // Promise(3) Promise(6).then(six => Promise(six / 2)) // Promise(3) Promise(6).map(six => six / 2) // Promise(3) Promise(6).chain(six => Promise(six / 2)) // Promise(3)
  • 74. Promise(6).then(six => six / 2) // Promise(3) Promise(6).then(six => Promise(six / 2)) // Promise(3) Promise(6).map(six => six / 2) // Promise(3) Promise(6).chain(six => Promise(six / 2)) // Promise(3)
  • 75. const contrivedEx2 = () => fs.readFile('cfg.json', 'utf-8', (err, contents) => { if(err) throw err const newContents = contents.replace(/8/g, '6') fs.writeFile('cfg1.json', newContents, (err, _) => { if(err) throw err console.log('success!') }) })
  • 76. const readFile = futurize(fs.readFile) const writeFile = futurize(fs.writeFile) const contrivedEx2 = () => readFile('cfg.json', 'utf-8') .map(contents => contents.replace(/8/g, '6')) .chain(replaced => writeFile('cfg1.json', replaced))
  • 77. const contrivedEx2 = () => fs.readFile('cfg.json', 'utf-8', (err, contents) => { if(err) throw err const newContents = contents.replace(/8/g, '6') fs.writeFile('cfg1.json', newContents, (err, _) => { if(err) throw err console.log('success!') }) }) const readFile = futurize(fs.readFile) const writeFile = futurize(fs.writeFile) const contrivedEx2 = () => readFile('cfg.json', 'utf-8') .map(contents => contents.replace(/8/g, '6')) .chain(replaced => writeFile('cfg1.json', replaced))
  • 78. const readFile = futurize(fs.readFile) const writeFile = futurize(fs.writeFile) const contrivedEx2 = () => readFile('cfg.json', 'utf-8') .map(contents => contents.replace(/8/g, '6')) .chain(replaced => writeFile('cfg1.json', replaced)) contrivedEx2().fork(e => console.error(e), r => console.log('success!'))
  • 79. const lib = username => getTweets(username) .map(ts => truncateTo130(ts)) .chain(ts => writeFile('tweets.json', ts)) lib(‘@drboolean’)
  • 80. const lib = username => getTweets(username) .map(ts => truncateTo130(ts)) .chain(ts => writeFile('tweets.json', ts)) lib(‘@drboolean’) .chain(f => saveToS3(f))
  • 81. const lib = username => getTweets(username) .map(ts => truncateTo130(ts)) .chain(ts => writeFile('tweets.json', ts)) lib(‘@drboolean’) .chain(f => saveToS3(f)) .fork(e => console.error(e), r => console.log(r))
  • 82.
  • 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"
  • 89. leftOrRight.fold(e => `we had an error: ${e}`, s => s.toUpperCase())
  • 90. Right({hair: 'brown'}) .map(obj => obj.hair) .map(brown => brown.length) .chain(five => Right(five * 2)) // Right(10)
  • 91. Left('ignored') .map(obj => obj.hair) .map(brown => brown.length) .chain(five => Left(five * 2)) // Left('ignored')
  • 92. const getConfig = () => { try { return fs.readFileSync('cfg.json') } catch(e) { return null } } const contrivedEx3 = () => { const cfg = getConfig() if(cfg) { const parsed = JSON.parse(cfg) return parsed.port } else { return 3000 } }
  • 93. const getConfig = () => Either.try(fs.readFileSync)('cfg.json') const contrivedEx3 = () => getConfig() .map(JSON.parse) .fold(e => 3000, c => c.port)
  • 94. const getConfig = () => Either.try(fs.readFileSync)('cfg.json') const contrivedEx3 = () => getConfig() .map(JSON.parse) .fold(e => 3000, c => c.port) const getConfig = () => { try { return fs.readFileSync('cfg.json') } catch(e) { return null } } const contrivedEx3 = () => { const cfg = getConfig() if(cfg) { const parsed = JSON.parse(cfg) return parsed.port } else { return 3000 } }
  • 95. Claim
  • 96. const contrivedEx4 = user => { const address = user.address if(address) { const zip = address.match(/(d{5})$/i) if(zip) { const city = cityByZip(zip) if(city) { return city } else { return "can't find city" } } } return "can't find city" }
  • 97. const contrivedEx4 = user => fromNullable(user.address) .chain(a => fromNullable(a.match(/(d{5})$/i))) .chain(zip => fromNullable(cityByZip(zip))) .fold(() => "can't find city", city => city)
  • 98. const contrivedEx4 = user => { const address = user.address if(address) { const zip = address.match(/(d{5})$/i) if(zip) { const city = cityByZip(zip) if(city) { return city } else { return "can't find city" } } } return "can't find city" } const contrivedEx4 = user => fromNullable(user.address) .chain(a => fromNullable(a.match(/(d{5})$/i))) .chain(zip => fromNullable(cityByZip(zip))) .fold(() => "can't find city", city => city)
  • 100. const depObjs = b => List(b.deps).flatMap(next => findDependencyByProject(next.Project.name, b.previous.deps) .fold(x => x, found => makeArgs(next, found))) const mapBuildsAndDepsForDiffQueue = (builds) => List(builds) .filter(b => b.previous) .flatMap(b => makeArgs(b, b.previous).concat(depObjs(b))) .filter(b => b) .toJS() const filterExistingDiffs = (items) => List(items).traverse(Task.of, (i) => find(Diff, { BuildId: i.buildId, DiffId: i.prevId, type: i.method }) .map(e => e.swap().getOrElse(null)) .map(bs => bs.filter(x => x).toJS())
  • 101. const buildProject = ({branch, sha}) => queueUnzipWwwOnS3(sha) .chain(() => isReleaseOrMainBranch(branch)) .fold(() => _.noop, () => generateReport(sha) .chain(queueDiffsForTileBuildsAndDeps) .chain(() => getHeadCommit(sha) .fold(() => Task.of(null), head => makeVrtDeployment(head, sha) .chain(() => createPrApp(head, sha)))) .fork(console.error, console.log))
  • 102.
  • 103.
  • 104. const vrtReport = ({sha, email, platforms}) => rejectFinishedPlatformOptions(platforms) .chain(plats => plats.map(gatherScreenshots)) .chain(shots => fromNullable(sha) .fold(() => findLastRef(), () => findBuild({sha})) .chain(ref => renderReport(shots, ref, email))) .fork(e => e, r => r)
  • 106. const getConfig = () => Either.try(fs.readFileSync)('cfg.json') const contrivedEx3 = () => getConfig() .map(JSON.parse) .fold(e => 3000, c => c.port)
  • 107. Safer
  • 108.
  • 109. const ProfileLink = user => <a href={`/users/${u.id}`}>{u.name}</a> const Header = str => <h1>Now Viewing {str}</h1>
  • 110. Component :: a -> JSX
  • 115. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f(x))) })
  • 116. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f(x))) }) const Heading = str => <h1>Now Viewing {str}</h1> const Title = Comp(Heading).contramap(s => s.pageName)
  • 117. const Title = Comp(Heading).contramap(s => s.pageName) Title.fold({ pageName: ‘Home', currentUser: { id: 2, name: 'Chris Harrison’ } }) // <h1>Now Viewing Home</h1> const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f(x))) }) const Heading = str => <h1>Now Viewing {str}</h1>
  • 118. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f(x))) })
  • 119. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f(x))), concat: other => Comp(x => <div>{g(x)} {other.fold(x)}</div>) })
  • 120. const ProfileLink = user => <a href={`/users/${u.id}`}>{u.name}</a>) const Heading = str => <h1>Now Viewing {str}</h1> const Heading = Comp(Title).contramap(s => s.pageName) const Link = Comp(ProfileLink).contramap(s => s.currentUser) const App = Heading.concat(Link)
  • 121. const ProfileLink = user => <a href={`/users/${u.id}`}>{u.name}</a>) const Heading = str => <h1>Now Viewing {str}</h1> const Heading = Comp(Title).contramap(s => s.pageName) const Link = Comp(ProfileLink).contramap(s => s.currentUser) const App = Heading.concat(Link) App.fold({ pageName: ‘Home', currentUser: { name: 'Chris Harrison’ } }) // <div> // <h1>Now Viewing Home</h1> // <a href="/users/22">Chris Harrison</a> // </div>
  • 122. Reducer :: (a, b) -> a
  • 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)) })
  • 127. const appReducer = Reducer((state, action) => { switch (action.type) { case 'set_visibility_filter': return Object.assign({}, state, { visibilityFilter: action.filter }) default: return state } })
  • 128. const todoReducer = Reducer((state, action) => { switch (action.type) { case 'new_todo': const t = { id: 0, title: action.payload.title } return Object.assign({}, state, { todos: state.todos.concat(t) }) default: return state } })
  • 129. const todoApp = appReducer .concat(todoReducer) .contramap(action => Object.assign({filter: 'all'}, action)) .map(s => Object.assign({}, s, {lastUpdated: Date()}))
  • 130. const todoApp = appReducer .concat(todoReducer) .contramap(action => Object.assign({filter: 'all'}, action)) .map(s => Object.assign({}, s, {lastUpdated: Date()})) todoApp.fold({visibilityFilter: ‘complete'}, {type: ‘set_visibility_filter'}) // { visibilityFilter: 'all', // lastUpdated: 'Sun Aug 21 2016 11:04:48 GMT-0700 (PDT)' }
  • 131. const todoApp = appReducer .contramap(action => Object.assign({filter: 'all'}, action)) .concat(todoReducer) .map(s => Object.assign({}, s, {lastUpdated: Date()})) todoApp.fold({visibilityFilter: ‘complete'}, {type: ‘set_visibility_filter'}) // { visibilityFilter: 'all', // lastUpdated: 'Sun Aug 21 2016 11:04:48 GMT-0700 (PDT)' }
  • 132. Hoc :: Component -> Component
  • 133. const Hoc = g => ({ fold: g, concat: other => Hoc(x => g(other.fold(x))) })
  • 134. const hoc = Hoc(withReducer(‘state', 'dispatch', todoApp.fold, {todos: []})) const Todos = hoc.fold(({ state, dispatch }) => <div> <span>Filter: {state.visibilityFilter}</span> <ul> { state.todos.map(t => <li>{t.title}</li>) } </ul> <button onClick={() => dispatch({ type: 'new_todo', payload: {title: 'New todo'}})}> Add Todo </button> <button onClick={() => dispatch({ type: 'set_visibility_filter' })}> Set Visibility </button> </div> )
  • 135. const App = Heading.contramap(s => s.pageName) .concat(TodoComp) .concat(Link.contramap(s => s.currentUser)) .fold({ pageName: 'Home', currentUser: {id: 2, name: 'Boris' } }) ReactDOM.render(App, document.getElementById('body')) const TodoComp = Component(classToFn(Todos)) const Heading = Component(s => <h1>Now Viewing {s}</h1>) const Link = Component(u => <a href={`/users/${u.id}`}>{u.name}</a>)
  • 137. map = compose = program construction
  • 138. // Functor Box.of(20).map(x => x / 2) // Box(10) // Monad Box.of(true).chain(x => Box.of(!x)) // Box(false) // Monoid Box.of('small').concat(Box.of('pox')) // Box('smallpox') // Applicative Box.of(x => x + 1).ap(2) // Box(3) // Traversable Box.of(3).traverse(Either.of, x => fromNullable(x)) // Right(Box(3)) // Natural transformation eitherToBox(fromNullable(null)) // Box(null)
  • 139.
  • 140.