SlideShare une entreprise Scribd logo
1  sur  143
Télécharger pour lire hors ligne
.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

Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sectoritnewsafrica
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Dernier (20)

Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

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.