SlideShare uma empresa Scribd logo
1 de 105
Baixar para ler offline
© 2016 Reginald Braithwaite. Some rights reserved. 1
JavaScript Combinators (2016)
© 2016 Reginald Braithwaite. Some rights reserved. 2
© 2016 Reginald Braithwaite. Some rights reserved. 3
we'll talk about
Using combinators for
decomposi2on and composi2on
© 2016 Reginald Braithwaite. Some rights reserved. 4
© 2016 Reginald Braithwaite. Some rights reserved. 5
and we'll think about
Making responsibili/es and
rela/onships explicit
© 2016 Reginald Braithwaite. Some rights reserved. 6
© 2016 Reginald Braithwaite. Some rights reserved. 7
© 2016 Reginald Braithwaite. Some rights reserved. 8
Decomposi)on
© 2016 Reginald Braithwaite. Some rights reserved. 9
We decompose en%%es to make
discreet responsibili%es explicit
© 2016 Reginald Braithwaite. Some rights reserved. 10
a monolith
Parse.User.logIn("user", "pass", {
success: function (user) {
query.find({
success: function (users) {
users[0].save({ key: value }, {
success: function (user) {
currentUser = user;
}
});
}
});
}
});
© 2016 Reginald Braithwaite. Some rights reserved. 11
decomposi)on by extrac)ng func)ons
let assignCurrentUser = (user) => {
currentUser = user;
};
let saveFirstUser = (users) =>
users[0].save({ key: value }, {
success: assignCurrentUser
});
let logUserIn = (user) =>
query.find({
success: saveFirstUser
});
Parse.User.logIn("user", "pass", {
success: logUserIn
});
© 2016 Reginald Braithwaite. Some rights reserved. 12
© 2016 Reginald Braithwaite. Some rights reserved. 13
Composi'on
© 2016 Reginald Braithwaite. Some rights reserved. 14
We compose en%%es to make the
rela%onships between them explicit
© 2016 Reginald Braithwaite. Some rights reserved. 15
promises explicitly compose asynchronous func3ons
let findUser = (user) => query.find();
let saveFirstUser = (user) => users[0].save({ key: value });
let assignCurrentUser = (user) => {
currentUser = user;
};
Parse.User.logIn("user", "pass")
.then(findUser)
.then(saveFirstUser)
.then(assignCurrentUser);
© 2016 Reginald Braithwaite. Some rights reserved. 16
© 2016 Reginald Braithwaite. Some rights reserved. 17
Decomposi)on is about en))es
© 2016 Reginald Braithwaite. Some rights reserved. 18
Composi'on is about rela'onships
© 2016 Reginald Braithwaite. Some rights reserved. 19
Back to decomposi.on
© 2016 Reginald Braithwaite. Some rights reserved. 20
extrac'ng named func'ons
The most obvious form of
decomposi2on
© 2016 Reginald Braithwaite. Some rights reserved. 21
© 2016 Reginald Braithwaite. Some rights reserved. 22
Extrac'ng func'ons works from the
inside-out
© 2016 Reginald Braithwaite. Some rights reserved. 23
extrac'ng named func'ons
Decomposi)on of Implementa)on
© 2016 Reginald Braithwaite. Some rights reserved. 24
Let's look at something else
© 2016 Reginald Braithwaite. Some rights reserved. 25
© 2016 Reginald Braithwaite. Some rights reserved. 26
pluck: "A convenient version of what is
perhaps the most common use-case for map,
extrac8ng a list of property values."
© 2016 Reginald Braithwaite. Some rights reserved. 27
let pluck = (collection, property) =>
collection.map( (obj) => obj[property] );
var deStijl = [
{name: 'Theo van Doesburg', occupation: 'theorist'},
{name: 'Piet Mondriaan', occupation: 'painter'},
{name: 'Gerrit Rietveld', occupation: 'architect'}];
pluck(deStijl, 'name')
//=> ["Theo van Doesburg", "Piet Mondriaan", "Gerrit Rietveld"]
© 2016 Reginald Braithwaite. Some rights reserved. 28
func%ons have interfaces
pluck's interface has two parts: The
collec0on, and the property
© 2016 Reginald Braithwaite. Some rights reserved. 29
manually decomposing pluck's interface
let pluckFrom = (collection) =>
(property) => pluck(collection, property);
var deStijl = [
{name: 'Theo van Doesburg', occupation: 'theorist'},
{name: 'Piet Mondriaan', occupation: 'painter'},
{name: 'Gerrit Rietveld', occupation: 'architect'}];
pluckFrom(deStijl)('name')
//=> ["Theo van Doesburg", "Piet Mondriaan", "Gerrit Rietveld"]
© 2016 Reginald Braithwaite. Some rights reserved. 30
manually decomposing pluck's interface
let pluckWith = (property) =>
(collection) => pluck(collection, property);
var deStijl = [
{name: 'Theo van Doesburg', occupation: 'theorist'},
{name: 'Piet Mondriaan', occupation: 'painter'},
{name: 'Gerrit Rietveld', occupation: 'architect'}];
pluckFrom(deStijl)('name')
//=> ["Theo van Doesburg", "Piet Mondriaan", "Gerrit Rietveld"]
© 2016 Reginald Braithwaite. Some rights reserved. 31
pluckFrom and pluckWith
par'ally apply pluck
© 2016 Reginald Braithwaite. Some rights reserved. 32
© 2016 Reginald Braithwaite. Some rights reserved. 33
Par$al applica$on decomposes
func$ons from the outside-in
© 2016 Reginald Braithwaite. Some rights reserved. 34
par$al applica$on
Decomposi)on of Interface
© 2016 Reginald Braithwaite. Some rights reserved. 35
© 2016 Reginald Braithwaite. Some rights reserved. 36
Decorators
© 2016 Reginald Braithwaite. Some rights reserved. 37
A decorator is a higher-order
func1on that takes a func1on, and
returns another func1on that adds
to or modifies its argument's
behaviour.
© 2016 Reginald Braithwaite. Some rights reserved. 38
par$al applica$on decomposes a func$on from the
outside-in
let pluck = (collection, property) =>
collection.map( (obj) => obj[property] );
// decomposes into:
let pluckFrom = (collection) =>
(property) => pluck(collection, property);
© 2016 Reginald Braithwaite. Some rights reserved. 39
extract closed-over binding
let pluckFrom = (collection) =>
(property) => pluck(collection, property);
// becomes:
let leftApply = (fn, a) =>
(b) => fn(a, b);
let pluckFrom = (collection) =>
leftApply(pluck, collection);
© 2016 Reginald Braithwaite. Some rights reserved. 40
extract closed-over binding
Closed over bindings can be
extracted, just like parameters
© 2016 Reginald Braithwaite. Some rights reserved. 41
extract closed-over binding
Decomposing pluckFrom into
leftApply gives us a decorator
© 2016 Reginald Braithwaite. Some rights reserved. 42
leftApply is a decorator that
decomposes a func1on's interface
© 2016 Reginald Braithwaite. Some rights reserved. 43
© 2016 Reginald Braithwaite. Some rights reserved. 44
hmmmm
What does
leftApply(leftApply,
leftApply) do?
© 2016 Reginald Braithwaite. Some rights reserved. 45
back to par*al applica*on
let rightApply = (fn, b) =>
(a) => fn(a, b);
let pluckWith = (property) =>
rightApply(pluck, property);
© 2016 Reginald Braithwaite. Some rights reserved. 46
more decomposi+on with par+al applica+on
let get = (object, property) =>
object[property];
get({name: 'Gerrit Rietveld'}, 'name')
//=> Gerrit Rietveld
let getWith = (property) => rightApply(get, property);
let nameOf = getWith('name');
nameOf({name: 'Gerrit Rietveld'})
//=> Gerrit Rietveld
© 2016 Reginald Braithwaite. Some rights reserved. 47
more decomposi+on with par+al applica+on
let map = (collection, fn) =>
collection.map(fn);
let mapWith = (fn) => rightApply(map, property);
© 2016 Reginald Braithwaite. Some rights reserved. 48
Back to composi,on
© 2016 Reginald Braithwaite. Some rights reserved. 49
© 2016 Reginald Braithwaite. Some rights reserved. 50
Simple Composi+on
© 2016 Reginald Braithwaite. Some rights reserved. 51
let compose = (a, b) =>
(c) => a(b(c));
© 2016 Reginald Braithwaite. Some rights reserved. 52
compose in ac&on
var deStijl = [
{name: 'Theo van Doesburg', occupation: 'theorist'},
{name: 'Piet Mondriaan', occupation: 'painter'},
{name: 'Gerrit Rietveld', occupation: 'architect'}];
let pluckWith = compose(mapWith, getWith);
let namesOf = pluckWith('name');
namesOf(deStijl)
//=> ["Theo van Doesburg","Piet Mondriaan","Gerrit Rietveld"]
© 2016 Reginald Braithwaite. Some rights reserved. 53
pluckWith =
compose(mapWith, getWith);
compose wires the output of one
func/on into the input of another
© 2016 Reginald Braithwaite. Some rights reserved. 54
© 2016 Reginald Braithwaite. Some rights reserved. 55
reminder:
We compose en**es to make the
rela*onships between them explicit
© 2016 Reginald Braithwaite. Some rights reserved. 56
More Composi+on
© 2016 Reginald Braithwaite. Some rights reserved. 57
let mix = (...ingredients) => console.log('mixing', ...ingredients);
let bake = () => console.log('baking');
let cool = () => console.log('cooling');
let makeBread = (...ingredients) => {
mix(...ingredients);
bake();
cool();
}
© 2016 Reginald Braithwaite. Some rights reserved. 58
composi'on with before
let before = (fn, decoration) =>
(...args) => {
decoration(...args);
return fn(...args);
};
let bakeBread = before(bake, mix);
let makeBread = (...ingredients) => {
bakeBread();
cool();
}
© 2016 Reginald Braithwaite. Some rights reserved. 59
before makes the )me rela)onship
between two func)ons explicit
© 2016 Reginald Braithwaite. Some rights reserved. 60
composi'on with after
let after = (fn, decoration) =>
(...args) => {
let returnValue = fn(...args);
decoration(...args);
return returnValue;
};
let bakeBread = before(bake, mix);
let makeBread = after(bakeBread, cool);
© 2016 Reginald Braithwaite. Some rights reserved. 61
after also makes the +me
rela+onship between two func+ons
explicit
© 2016 Reginald Braithwaite. Some rights reserved. 62
decomposing before
let beforeWith = (decoration) =>
rightApply(before, decoration);
let mixBefore = beforeWith(mix);
let bakeBread = mixBefore(bake);
© 2016 Reginald Braithwaite. Some rights reserved. 63
decomposing after
let afterWith = (decoration) =>
rightApply(after, decoration);
let coolAfter = afterWith(after);
let makeBread = coolAfter(bakeBread);
© 2016 Reginald Braithwaite. Some rights reserved. 64
beforeWith and afterWith are
combinators that turn func1ons into
decorators that compose behaviour
© 2016 Reginald Braithwaite. Some rights reserved. 65
© 2016 Reginald Braithwaite. Some rights reserved. 66
© 2016 Reginald Braithwaite. Some rights reserved. 67
JavaScript invoca-ons are coloured
© 2016 Reginald Braithwaite. Some rights reserved. 68
coloured decorators
let before = (fn, decoration) =>
function (...args) {
decoration.apply(this, args);
return fn.apply(this, args);
};
let after = (fn, decoration) =>
function (...args) {
let returnValue = fn.apply(this, args);
decoration.apply(this, args);
return returnValue;
};
© 2016 Reginald Braithwaite. Some rights reserved. 69
Why coloured decorators ma0er
© 2016 Reginald Braithwaite. Some rights reserved. 70
bread, revisited
class Bread {
constructor (...ingredients) {
this.ingredients = ingredients;
}
mix () {
console.log('mixing', ...this.ingredients)
};
bake () {
console.log('baking');
}
cool () {
console.log('cooling');
}
make () {
this.mix();
this.bake();
this.cool();
}
}
© 2016 Reginald Braithwaite. Some rights reserved. 71
bread, revisited
class Bread {
// ...
make () {
this.mix();
this.bake();
this.cool();
}
}
© 2016 Reginald Braithwaite. Some rights reserved. 72
Classes can be decorated too
© 2016 Reginald Braithwaite. Some rights reserved. 73
beforeAll
const beforeAll = (behaviour, ...methodNames) =>
(clazz) => {
for (let methodName of methodNames) {
const method = clazz.prototype[methodName];
Object.defineProperty(clazz.prototype, property, {
value: function (...args) {
behaviour.apply(this, args);
return method.apply(this, args);
},
writable: true
});
}
return clazz;
};
© 2016 Reginald Braithwaite. Some rights reserved. 74
afterAll
const afterAll = (behaviour, ...methodNames) =>
(clazz) => {
for (let methodName of methodNames) {
const method = clazz.prototype[methodName];
Object.defineProperty(clazz.prototype, property, {
value: function (...args) {
const returnValue = method.apply(this, args);
behaviour.apply(this, args);
return returnValue;
},
writable: true
});
}
return clazz;
};
© 2016 Reginald Braithwaite. Some rights reserved. 75
be#er bread
let invoke = (methodName) => function (...args) {
return this[methodName](...args);
}
let Bread = beforeAll(invoke('mix'), 'make')(
afterAll(invoke('cool'), 'make')(class {
// ...
make () {
this.bake();
}
})
);
© 2016 Reginald Braithwaite. Some rights reserved. 76
© 2016 Reginald Braithwaite. Some rights reserved. 77
Looking Forward
© 2016 Reginald Braithwaite. Some rights reserved. 78
ES.who-knows-when
© 2016 Reginald Braithwaite. Some rights reserved. 79
be#er bread with class decorator sugar
let invoke = (methodName) => function (...args) {
return this[methodName](...args);
}
@beforeAll(invoke('mix'), 'make')
@afterAll(invoke('cool'), 'make')
class Bread {
// ...
make () {
this.bake();
}
}
© 2016 Reginald Braithwaite. Some rights reserved. 80
method decorators
let methodDecorator = (decorator) =>
function (target, name, descriptor) {
descriptor.value = decorator(descriptor.value);
}
let invokeBefore = (methodName) =>
methodDecorator( (methodBody) =>
before(methodBody, invoke(methodName))
);
let invokeAfter = (methodName) =>
methodDecorator( (methodBody) =>
after(methodBody, invoke(methodName))
);
© 2016 Reginald Braithwaite. Some rights reserved. 81
be#er bread
class Bread {
// ...
@invokeBefore('mix')
@invokeAfter('cool')
make () {
this.bake();
}
}
© 2016 Reginald Braithwaite. Some rights reserved. 82
© 2016 Reginald Braithwaite. Some rights reserved. 83
What have we seen so far?
© 2016 Reginald Braithwaite. Some rights reserved. 84
What have we seen so far?
• Extract func,on
• Promise interface
• Par,al applica,on
• Extract closed-over binding
(more!)
© 2016 Reginald Braithwaite. Some rights reserved. 85
What have we seen so far?
• Simple composi,on
• Composi,on decorators
• Class decorators
• Method decorators
© 2016 Reginald Braithwaite. Some rights reserved. 86
Don't worry about the details!
© 2016 Reginald Braithwaite. Some rights reserved. 87
© 2016 Reginald Braithwaite. Some rights reserved. 88
it's all the same idea
Decomposi)on makes
responsibili)es explicit
© 2016 Reginald Braithwaite. Some rights reserved. 89
© 2016 Reginald Braithwaite. Some rights reserved. 90
and it's all the same idea
Composi'on makes rela'onships
explicit
© 2016 Reginald Braithwaite. Some rights reserved. 91
These ideas ma*er
© 2016 Reginald Braithwaite. Some rights reserved. 92
There are only two hard problems in
Computer Science: Cache
invalida9on, and naming things.
© 2016 Reginald Braithwaite. Some rights reserved. 93
© 2016 Reginald Braithwaite. Some rights reserved. 94
Naming en))es is hard because you
have to figure out which en))es
need to be named
© 2016 Reginald Braithwaite. Some rights reserved. 95
© 2016 Reginald Braithwaite. Some rights reserved. 96
Naming rela+onships is hard
because you have to figure out
which rela+onships need to be
named
© 2016 Reginald Braithwaite. Some rights reserved. 97
© 2016 Reginald Braithwaite. Some rights reserved. 98
Combinators do not make naming
easy
© 2016 Reginald Braithwaite. Some rights reserved. 99
© 2016 Reginald Braithwaite. Some rights reserved. 100
Combinators give us a language for
naming things
© 2016 Reginald Braithwaite. Some rights reserved. 101
© 2016 Reginald Braithwaite. Some rights reserved. 102
Do not follow
in the footsteps of the sages.
© 2016 Reginald Braithwaite. Some rights reserved. 103
Seek what they sought.
© 2016 Reginald Braithwaite. Some rights reserved. 104
Reg Braithwaite
PagerDuty, Inc.
raganwald.com
@raganwald
© 2016 Reginald Braithwaite. Some rights reserved. 105

Mais conteúdo relacionado

Semelhante a Javascript Combinators (2016)

Hacktoberfest - Presentation Template 2022 Event Kit.pptx
Hacktoberfest - Presentation Template 2022 Event Kit.pptxHacktoberfest - Presentation Template 2022 Event Kit.pptx
Hacktoberfest - Presentation Template 2022 Event Kit.pptxakashuday1
 
Managing Github via Terrafom.pdf
Managing Github via Terrafom.pdfManaging Github via Terrafom.pdf
Managing Github via Terrafom.pdfmicharaeck
 
Full Stack Visualization: Build A React App With A Sankey Diagram
Full Stack Visualization: Build A React App With A Sankey DiagramFull Stack Visualization: Build A React App With A Sankey Diagram
Full Stack Visualization: Build A React App With A Sankey DiagramNeo4j
 
OSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKay
OSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKayOSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKay
OSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKayNETWAYS
 
BeJUG Meetup - What's coming in the OSGi R7 Specification
BeJUG Meetup - What's coming in the OSGi R7 SpecificationBeJUG Meetup - What's coming in the OSGi R7 Specification
BeJUG Meetup - What's coming in the OSGi R7 SpecificationStijn Van Den Enden
 
Pentesting an unfriendly environment: bypassing (un)common defences and mate ...
Pentesting an unfriendly environment: bypassing (un)common defences and mate ...Pentesting an unfriendly environment: bypassing (un)common defences and mate ...
Pentesting an unfriendly environment: bypassing (un)common defences and mate ...Sandro Zaccarini
 
Essential git fu for tech writers
Essential git fu for tech writersEssential git fu for tech writers
Essential git fu for tech writersGaurav Nelson
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegelermfrancis
 
Working with the Scalding Type-Safe API
Working with the Scalding Type-Safe API Working with the Scalding Type-Safe API
Working with the Scalding Type-Safe API Criteolabs
 
2020 03-26 - meet up - zparkio
2020 03-26 - meet up - zparkio2020 03-26 - meet up - zparkio
2020 03-26 - meet up - zparkioLeo Benkel
 
Android Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyondAndroid Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyondRamon Ribeiro Rabello
 
How to cross compile ROS2 distro by taken VxWorks RTOS as an example
How to cross compile ROS2 distro by taken VxWorks RTOS as an exampleHow to cross compile ROS2 distro by taken VxWorks RTOS as an example
How to cross compile ROS2 distro by taken VxWorks RTOS as an exampleAndrei Kholodnyi
 
Introduction to R2DBC
Introduction to R2DBCIntroduction to R2DBC
Introduction to R2DBCRob Hedgpeth
 
Criteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupCriteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupIbrahim Abubakari
 
201907 Lightening UED1.pdf
201907 Lightening UED1.pdf201907 Lightening UED1.pdf
201907 Lightening UED1.pdfJiaWen Shen
 
Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM ICF CIRCUIT
 
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D BosschaertLeveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaertmfrancis
 
Getting Started with MATLAB and OCTAVE for engineers
Getting Started with MATLAB and OCTAVE for engineersGetting Started with MATLAB and OCTAVE for engineers
Getting Started with MATLAB and OCTAVE for engineersRathish Chandra Gatti,Ph.D
 

Semelhante a Javascript Combinators (2016) (20)

Hacktoberfest - Presentation Template 2022 Event Kit.pptx
Hacktoberfest - Presentation Template 2022 Event Kit.pptxHacktoberfest - Presentation Template 2022 Event Kit.pptx
Hacktoberfest - Presentation Template 2022 Event Kit.pptx
 
Managing Github via Terrafom.pdf
Managing Github via Terrafom.pdfManaging Github via Terrafom.pdf
Managing Github via Terrafom.pdf
 
Full Stack Visualization: Build A React App With A Sankey Diagram
Full Stack Visualization: Build A React App With A Sankey DiagramFull Stack Visualization: Build A React App With A Sankey Diagram
Full Stack Visualization: Build A React App With A Sankey Diagram
 
OSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKay
OSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKayOSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKay
OSMC 2019 | The Telegraf Toolbelt: It Can Do That, Really? by David McKay
 
BeJUG Meetup - What's coming in the OSGi R7 Specification
BeJUG Meetup - What's coming in the OSGi R7 SpecificationBeJUG Meetup - What's coming in the OSGi R7 Specification
BeJUG Meetup - What's coming in the OSGi R7 Specification
 
Pentesting an unfriendly environment: bypassing (un)common defences and mate ...
Pentesting an unfriendly environment: bypassing (un)common defences and mate ...Pentesting an unfriendly environment: bypassing (un)common defences and mate ...
Pentesting an unfriendly environment: bypassing (un)common defences and mate ...
 
Essential git fu for tech writers
Essential git fu for tech writersEssential git fu for tech writers
Essential git fu for tech writers
 
Os Davis
Os DavisOs Davis
Os Davis
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
 
Working with the Scalding Type -Safe API
Working with the Scalding Type -Safe APIWorking with the Scalding Type -Safe API
Working with the Scalding Type -Safe API
 
Working with the Scalding Type-Safe API
Working with the Scalding Type-Safe API Working with the Scalding Type-Safe API
Working with the Scalding Type-Safe API
 
2020 03-26 - meet up - zparkio
2020 03-26 - meet up - zparkio2020 03-26 - meet up - zparkio
2020 03-26 - meet up - zparkio
 
Android Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyondAndroid Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyond
 
How to cross compile ROS2 distro by taken VxWorks RTOS as an example
How to cross compile ROS2 distro by taken VxWorks RTOS as an exampleHow to cross compile ROS2 distro by taken VxWorks RTOS as an example
How to cross compile ROS2 distro by taken VxWorks RTOS as an example
 
Introduction to R2DBC
Introduction to R2DBCIntroduction to R2DBC
Introduction to R2DBC
 
Criteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupCriteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) Meetup
 
201907 Lightening UED1.pdf
201907 Lightening UED1.pdf201907 Lightening UED1.pdf
201907 Lightening UED1.pdf
 
Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM
 
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D BosschaertLeveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
 
Getting Started with MATLAB and OCTAVE for engineers
Getting Started with MATLAB and OCTAVE for engineersGetting Started with MATLAB and OCTAVE for engineers
Getting Started with MATLAB and OCTAVE for engineers
 

Mais de Reginald Braithwaite

Mais de Reginald Braithwaite (6)

Vital JavaScript
Vital JavaScriptVital JavaScript
Vital JavaScript
 
I have a good feeling about this
I have a good feeling about thisI have a good feeling about this
I have a good feeling about this
 
What we lost in the fire
What we lost in the fireWhat we lost in the fire
What we lost in the fire
 
languages: it's time for change
languages: it's time for changelanguages: it's time for change
languages: it's time for change
 
The not so-big software design
The not so-big software designThe not so-big software design
The not so-big software design
 
The Rebellion Imperative
The Rebellion ImperativeThe Rebellion Imperative
The Rebellion Imperative
 

Último

Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456KiaraTiradoMicha
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyAnusha Are
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxalwaysnagaraju26
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 

Último (20)

Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 

Javascript Combinators (2016)

  • 1. © 2016 Reginald Braithwaite. Some rights reserved. 1
  • 2. JavaScript Combinators (2016) © 2016 Reginald Braithwaite. Some rights reserved. 2
  • 3. © 2016 Reginald Braithwaite. Some rights reserved. 3
  • 4. we'll talk about Using combinators for decomposi2on and composi2on © 2016 Reginald Braithwaite. Some rights reserved. 4
  • 5. © 2016 Reginald Braithwaite. Some rights reserved. 5
  • 6. and we'll think about Making responsibili/es and rela/onships explicit © 2016 Reginald Braithwaite. Some rights reserved. 6
  • 7. © 2016 Reginald Braithwaite. Some rights reserved. 7
  • 8. © 2016 Reginald Braithwaite. Some rights reserved. 8
  • 9. Decomposi)on © 2016 Reginald Braithwaite. Some rights reserved. 9
  • 10. We decompose en%%es to make discreet responsibili%es explicit © 2016 Reginald Braithwaite. Some rights reserved. 10
  • 11. a monolith Parse.User.logIn("user", "pass", { success: function (user) { query.find({ success: function (users) { users[0].save({ key: value }, { success: function (user) { currentUser = user; } }); } }); } }); © 2016 Reginald Braithwaite. Some rights reserved. 11
  • 12. decomposi)on by extrac)ng func)ons let assignCurrentUser = (user) => { currentUser = user; }; let saveFirstUser = (users) => users[0].save({ key: value }, { success: assignCurrentUser }); let logUserIn = (user) => query.find({ success: saveFirstUser }); Parse.User.logIn("user", "pass", { success: logUserIn }); © 2016 Reginald Braithwaite. Some rights reserved. 12
  • 13. © 2016 Reginald Braithwaite. Some rights reserved. 13
  • 14. Composi'on © 2016 Reginald Braithwaite. Some rights reserved. 14
  • 15. We compose en%%es to make the rela%onships between them explicit © 2016 Reginald Braithwaite. Some rights reserved. 15
  • 16. promises explicitly compose asynchronous func3ons let findUser = (user) => query.find(); let saveFirstUser = (user) => users[0].save({ key: value }); let assignCurrentUser = (user) => { currentUser = user; }; Parse.User.logIn("user", "pass") .then(findUser) .then(saveFirstUser) .then(assignCurrentUser); © 2016 Reginald Braithwaite. Some rights reserved. 16
  • 17. © 2016 Reginald Braithwaite. Some rights reserved. 17
  • 18. Decomposi)on is about en))es © 2016 Reginald Braithwaite. Some rights reserved. 18
  • 19. Composi'on is about rela'onships © 2016 Reginald Braithwaite. Some rights reserved. 19
  • 20. Back to decomposi.on © 2016 Reginald Braithwaite. Some rights reserved. 20
  • 21. extrac'ng named func'ons The most obvious form of decomposi2on © 2016 Reginald Braithwaite. Some rights reserved. 21
  • 22. © 2016 Reginald Braithwaite. Some rights reserved. 22
  • 23. Extrac'ng func'ons works from the inside-out © 2016 Reginald Braithwaite. Some rights reserved. 23
  • 24. extrac'ng named func'ons Decomposi)on of Implementa)on © 2016 Reginald Braithwaite. Some rights reserved. 24
  • 25. Let's look at something else © 2016 Reginald Braithwaite. Some rights reserved. 25
  • 26. © 2016 Reginald Braithwaite. Some rights reserved. 26
  • 27. pluck: "A convenient version of what is perhaps the most common use-case for map, extrac8ng a list of property values." © 2016 Reginald Braithwaite. Some rights reserved. 27
  • 28. let pluck = (collection, property) => collection.map( (obj) => obj[property] ); var deStijl = [ {name: 'Theo van Doesburg', occupation: 'theorist'}, {name: 'Piet Mondriaan', occupation: 'painter'}, {name: 'Gerrit Rietveld', occupation: 'architect'}]; pluck(deStijl, 'name') //=> ["Theo van Doesburg", "Piet Mondriaan", "Gerrit Rietveld"] © 2016 Reginald Braithwaite. Some rights reserved. 28
  • 29. func%ons have interfaces pluck's interface has two parts: The collec0on, and the property © 2016 Reginald Braithwaite. Some rights reserved. 29
  • 30. manually decomposing pluck's interface let pluckFrom = (collection) => (property) => pluck(collection, property); var deStijl = [ {name: 'Theo van Doesburg', occupation: 'theorist'}, {name: 'Piet Mondriaan', occupation: 'painter'}, {name: 'Gerrit Rietveld', occupation: 'architect'}]; pluckFrom(deStijl)('name') //=> ["Theo van Doesburg", "Piet Mondriaan", "Gerrit Rietveld"] © 2016 Reginald Braithwaite. Some rights reserved. 30
  • 31. manually decomposing pluck's interface let pluckWith = (property) => (collection) => pluck(collection, property); var deStijl = [ {name: 'Theo van Doesburg', occupation: 'theorist'}, {name: 'Piet Mondriaan', occupation: 'painter'}, {name: 'Gerrit Rietveld', occupation: 'architect'}]; pluckFrom(deStijl)('name') //=> ["Theo van Doesburg", "Piet Mondriaan", "Gerrit Rietveld"] © 2016 Reginald Braithwaite. Some rights reserved. 31
  • 32. pluckFrom and pluckWith par'ally apply pluck © 2016 Reginald Braithwaite. Some rights reserved. 32
  • 33. © 2016 Reginald Braithwaite. Some rights reserved. 33
  • 34. Par$al applica$on decomposes func$ons from the outside-in © 2016 Reginald Braithwaite. Some rights reserved. 34
  • 35. par$al applica$on Decomposi)on of Interface © 2016 Reginald Braithwaite. Some rights reserved. 35
  • 36. © 2016 Reginald Braithwaite. Some rights reserved. 36
  • 37. Decorators © 2016 Reginald Braithwaite. Some rights reserved. 37
  • 38. A decorator is a higher-order func1on that takes a func1on, and returns another func1on that adds to or modifies its argument's behaviour. © 2016 Reginald Braithwaite. Some rights reserved. 38
  • 39. par$al applica$on decomposes a func$on from the outside-in let pluck = (collection, property) => collection.map( (obj) => obj[property] ); // decomposes into: let pluckFrom = (collection) => (property) => pluck(collection, property); © 2016 Reginald Braithwaite. Some rights reserved. 39
  • 40. extract closed-over binding let pluckFrom = (collection) => (property) => pluck(collection, property); // becomes: let leftApply = (fn, a) => (b) => fn(a, b); let pluckFrom = (collection) => leftApply(pluck, collection); © 2016 Reginald Braithwaite. Some rights reserved. 40
  • 41. extract closed-over binding Closed over bindings can be extracted, just like parameters © 2016 Reginald Braithwaite. Some rights reserved. 41
  • 42. extract closed-over binding Decomposing pluckFrom into leftApply gives us a decorator © 2016 Reginald Braithwaite. Some rights reserved. 42
  • 43. leftApply is a decorator that decomposes a func1on's interface © 2016 Reginald Braithwaite. Some rights reserved. 43
  • 44. © 2016 Reginald Braithwaite. Some rights reserved. 44
  • 45. hmmmm What does leftApply(leftApply, leftApply) do? © 2016 Reginald Braithwaite. Some rights reserved. 45
  • 46. back to par*al applica*on let rightApply = (fn, b) => (a) => fn(a, b); let pluckWith = (property) => rightApply(pluck, property); © 2016 Reginald Braithwaite. Some rights reserved. 46
  • 47. more decomposi+on with par+al applica+on let get = (object, property) => object[property]; get({name: 'Gerrit Rietveld'}, 'name') //=> Gerrit Rietveld let getWith = (property) => rightApply(get, property); let nameOf = getWith('name'); nameOf({name: 'Gerrit Rietveld'}) //=> Gerrit Rietveld © 2016 Reginald Braithwaite. Some rights reserved. 47
  • 48. more decomposi+on with par+al applica+on let map = (collection, fn) => collection.map(fn); let mapWith = (fn) => rightApply(map, property); © 2016 Reginald Braithwaite. Some rights reserved. 48
  • 49. Back to composi,on © 2016 Reginald Braithwaite. Some rights reserved. 49
  • 50. © 2016 Reginald Braithwaite. Some rights reserved. 50
  • 51. Simple Composi+on © 2016 Reginald Braithwaite. Some rights reserved. 51
  • 52. let compose = (a, b) => (c) => a(b(c)); © 2016 Reginald Braithwaite. Some rights reserved. 52
  • 53. compose in ac&on var deStijl = [ {name: 'Theo van Doesburg', occupation: 'theorist'}, {name: 'Piet Mondriaan', occupation: 'painter'}, {name: 'Gerrit Rietveld', occupation: 'architect'}]; let pluckWith = compose(mapWith, getWith); let namesOf = pluckWith('name'); namesOf(deStijl) //=> ["Theo van Doesburg","Piet Mondriaan","Gerrit Rietveld"] © 2016 Reginald Braithwaite. Some rights reserved. 53
  • 54. pluckWith = compose(mapWith, getWith); compose wires the output of one func/on into the input of another © 2016 Reginald Braithwaite. Some rights reserved. 54
  • 55. © 2016 Reginald Braithwaite. Some rights reserved. 55
  • 56. reminder: We compose en**es to make the rela*onships between them explicit © 2016 Reginald Braithwaite. Some rights reserved. 56
  • 57. More Composi+on © 2016 Reginald Braithwaite. Some rights reserved. 57
  • 58. let mix = (...ingredients) => console.log('mixing', ...ingredients); let bake = () => console.log('baking'); let cool = () => console.log('cooling'); let makeBread = (...ingredients) => { mix(...ingredients); bake(); cool(); } © 2016 Reginald Braithwaite. Some rights reserved. 58
  • 59. composi'on with before let before = (fn, decoration) => (...args) => { decoration(...args); return fn(...args); }; let bakeBread = before(bake, mix); let makeBread = (...ingredients) => { bakeBread(); cool(); } © 2016 Reginald Braithwaite. Some rights reserved. 59
  • 60. before makes the )me rela)onship between two func)ons explicit © 2016 Reginald Braithwaite. Some rights reserved. 60
  • 61. composi'on with after let after = (fn, decoration) => (...args) => { let returnValue = fn(...args); decoration(...args); return returnValue; }; let bakeBread = before(bake, mix); let makeBread = after(bakeBread, cool); © 2016 Reginald Braithwaite. Some rights reserved. 61
  • 62. after also makes the +me rela+onship between two func+ons explicit © 2016 Reginald Braithwaite. Some rights reserved. 62
  • 63. decomposing before let beforeWith = (decoration) => rightApply(before, decoration); let mixBefore = beforeWith(mix); let bakeBread = mixBefore(bake); © 2016 Reginald Braithwaite. Some rights reserved. 63
  • 64. decomposing after let afterWith = (decoration) => rightApply(after, decoration); let coolAfter = afterWith(after); let makeBread = coolAfter(bakeBread); © 2016 Reginald Braithwaite. Some rights reserved. 64
  • 65. beforeWith and afterWith are combinators that turn func1ons into decorators that compose behaviour © 2016 Reginald Braithwaite. Some rights reserved. 65
  • 66. © 2016 Reginald Braithwaite. Some rights reserved. 66
  • 67. © 2016 Reginald Braithwaite. Some rights reserved. 67
  • 68. JavaScript invoca-ons are coloured © 2016 Reginald Braithwaite. Some rights reserved. 68
  • 69. coloured decorators let before = (fn, decoration) => function (...args) { decoration.apply(this, args); return fn.apply(this, args); }; let after = (fn, decoration) => function (...args) { let returnValue = fn.apply(this, args); decoration.apply(this, args); return returnValue; }; © 2016 Reginald Braithwaite. Some rights reserved. 69
  • 70. Why coloured decorators ma0er © 2016 Reginald Braithwaite. Some rights reserved. 70
  • 71. bread, revisited class Bread { constructor (...ingredients) { this.ingredients = ingredients; } mix () { console.log('mixing', ...this.ingredients) }; bake () { console.log('baking'); } cool () { console.log('cooling'); } make () { this.mix(); this.bake(); this.cool(); } } © 2016 Reginald Braithwaite. Some rights reserved. 71
  • 72. bread, revisited class Bread { // ... make () { this.mix(); this.bake(); this.cool(); } } © 2016 Reginald Braithwaite. Some rights reserved. 72
  • 73. Classes can be decorated too © 2016 Reginald Braithwaite. Some rights reserved. 73
  • 74. beforeAll const beforeAll = (behaviour, ...methodNames) => (clazz) => { for (let methodName of methodNames) { const method = clazz.prototype[methodName]; Object.defineProperty(clazz.prototype, property, { value: function (...args) { behaviour.apply(this, args); return method.apply(this, args); }, writable: true }); } return clazz; }; © 2016 Reginald Braithwaite. Some rights reserved. 74
  • 75. afterAll const afterAll = (behaviour, ...methodNames) => (clazz) => { for (let methodName of methodNames) { const method = clazz.prototype[methodName]; Object.defineProperty(clazz.prototype, property, { value: function (...args) { const returnValue = method.apply(this, args); behaviour.apply(this, args); return returnValue; }, writable: true }); } return clazz; }; © 2016 Reginald Braithwaite. Some rights reserved. 75
  • 76. be#er bread let invoke = (methodName) => function (...args) { return this[methodName](...args); } let Bread = beforeAll(invoke('mix'), 'make')( afterAll(invoke('cool'), 'make')(class { // ... make () { this.bake(); } }) ); © 2016 Reginald Braithwaite. Some rights reserved. 76
  • 77. © 2016 Reginald Braithwaite. Some rights reserved. 77
  • 78. Looking Forward © 2016 Reginald Braithwaite. Some rights reserved. 78
  • 79. ES.who-knows-when © 2016 Reginald Braithwaite. Some rights reserved. 79
  • 80. be#er bread with class decorator sugar let invoke = (methodName) => function (...args) { return this[methodName](...args); } @beforeAll(invoke('mix'), 'make') @afterAll(invoke('cool'), 'make') class Bread { // ... make () { this.bake(); } } © 2016 Reginald Braithwaite. Some rights reserved. 80
  • 81. method decorators let methodDecorator = (decorator) => function (target, name, descriptor) { descriptor.value = decorator(descriptor.value); } let invokeBefore = (methodName) => methodDecorator( (methodBody) => before(methodBody, invoke(methodName)) ); let invokeAfter = (methodName) => methodDecorator( (methodBody) => after(methodBody, invoke(methodName)) ); © 2016 Reginald Braithwaite. Some rights reserved. 81
  • 82. be#er bread class Bread { // ... @invokeBefore('mix') @invokeAfter('cool') make () { this.bake(); } } © 2016 Reginald Braithwaite. Some rights reserved. 82
  • 83. © 2016 Reginald Braithwaite. Some rights reserved. 83
  • 84. What have we seen so far? © 2016 Reginald Braithwaite. Some rights reserved. 84
  • 85. What have we seen so far? • Extract func,on • Promise interface • Par,al applica,on • Extract closed-over binding (more!) © 2016 Reginald Braithwaite. Some rights reserved. 85
  • 86. What have we seen so far? • Simple composi,on • Composi,on decorators • Class decorators • Method decorators © 2016 Reginald Braithwaite. Some rights reserved. 86
  • 87. Don't worry about the details! © 2016 Reginald Braithwaite. Some rights reserved. 87
  • 88. © 2016 Reginald Braithwaite. Some rights reserved. 88
  • 89. it's all the same idea Decomposi)on makes responsibili)es explicit © 2016 Reginald Braithwaite. Some rights reserved. 89
  • 90. © 2016 Reginald Braithwaite. Some rights reserved. 90
  • 91. and it's all the same idea Composi'on makes rela'onships explicit © 2016 Reginald Braithwaite. Some rights reserved. 91
  • 92. These ideas ma*er © 2016 Reginald Braithwaite. Some rights reserved. 92
  • 93. There are only two hard problems in Computer Science: Cache invalida9on, and naming things. © 2016 Reginald Braithwaite. Some rights reserved. 93
  • 94. © 2016 Reginald Braithwaite. Some rights reserved. 94
  • 95. Naming en))es is hard because you have to figure out which en))es need to be named © 2016 Reginald Braithwaite. Some rights reserved. 95
  • 96. © 2016 Reginald Braithwaite. Some rights reserved. 96
  • 97. Naming rela+onships is hard because you have to figure out which rela+onships need to be named © 2016 Reginald Braithwaite. Some rights reserved. 97
  • 98. © 2016 Reginald Braithwaite. Some rights reserved. 98
  • 99. Combinators do not make naming easy © 2016 Reginald Braithwaite. Some rights reserved. 99
  • 100. © 2016 Reginald Braithwaite. Some rights reserved. 100
  • 101. Combinators give us a language for naming things © 2016 Reginald Braithwaite. Some rights reserved. 101
  • 102. © 2016 Reginald Braithwaite. Some rights reserved. 102
  • 103. Do not follow in the footsteps of the sages. © 2016 Reginald Braithwaite. Some rights reserved. 103
  • 104. Seek what they sought. © 2016 Reginald Braithwaite. Some rights reserved. 104
  • 105. Reg Braithwaite PagerDuty, Inc. raganwald.com @raganwald © 2016 Reginald Braithwaite. Some rights reserved. 105