SlideShare a Scribd company logo
Thinking Functionally
Functional Programming using JavaScript
Luis Atencio
@luijar
Blog: http://luisatencio.net
What is FP?
“Functional programming refers to the
declarative evaluation of pure functions to
create immutable programs by avoiding
externally observable side effects.”
Why?
• Reduce complexity
• Create code that is easier to trace, debug, and
test
• Modularize code leads to separation of concerns
• Avoid duplications
• Implement changes unobtrusively
• Create code that is extensible and configurable
• Foundation for Rx and reactive programming
Why Learn it now?
• Most newer languages are/have incorporated
functional features into them.
– Java (streams, function interfaces, lambda
expressions)
– Scala (hybrid FP + OO)
– F# (immutable structures, pipes)
• LINQ
– ES6 JavaScript -> ES7 JavaScript will have streams
– Clojure, Lisp, Scheme, Haskell, OCaml, Erlang, etc
• We live in a highly concurrent world
Paradigm shift
• Eliminate externally observable side effects
• Control (reduce or eliminate) mutations
• Write declaratively and point-free
• Everything is a value (even functions)
• Functions ALWAYS return values
• Recursion as looping mechanism (eliminate
loops)
5
The OO World
6
Data and behavior tightly
coupled
ClassA
data
behavior
ClassB
data
behavior
ClassC
data
behavior Unit testing is challenging
Unit of work: Classes
function doWork(objectA): objectB
The FP World
function doMoreWork(objectB): objectC
function displayResults(objectC)
Data and behavior loosely
coupled
Unit testing is (basically)
free
Unit of work: Function
Is JavaScript functional?
JavaScript is a dynamic, object-oriented programing
language whose expressive power via closures and
high-order functions makes it compelling for writing in
a functional style.
Features that favor functional programming:
• const keyword
• Promises
• Lambda expressions + closures
• Generators and Iterators
• FP libraries (Ramda.js, Underscore.js, Lodash.js, etc)
Hello World!
document.getElementById('msg').innerHTML = '<h1>Hello World</h1>';
compose(addToDom('#msg'), h1)('Hello World');
vs
More functional Hello World!
compose (
addToDom('#msg'),
h2,
repeat(3))('Hello World');
Declarative & configurable
Even more functional Hello World!
compose (
addToDom('#msg'),
h2,
repeat(3),
escapeChars)('Hello World');
Extensible
Declarative Programming
• Describe WHAT a program does
• Not HOW to do it
SQL>
SELECT firstname, birthYear FROM Person
WHERE year > 1903 AND country = 'US'
GROUP BY firstname, birthYear
FP>
compose(select(firstname, birthYear),
from('Person'),
where(year => year === 1903),
where(country => country === 'US'),
groupBy(firstname, birthYear))(query);
First let’s look at the current
state of things
Imperative Programming
function addToTable(personId) {
if(personId != null) {
personId = studentId.replace(/^s*|-|s*$/g, '');
if(personId.length !== 9) {
throw new Error('Invalid Input');
}
var person = db.get(personId);
if (person) {
var rowInfo =
`<td>${person.ssn}</td>
<td>${person.firstname}</td>
<td>${person.lastname}</td>`;
$(`#${tableId}
tr:last`).after(`<tr>${rowInfo}</tr>`);
return $(`#${tableId} tr`).length - 1;
}
else {
throw new Error('Person Record not found!');
}
}
else {
return 0;
}
}
… after thinking functionally…
…and some magic…
var addToTable = compose(
appendToTable(’personTable'),
populateRow,
props(['ssn', 'firstname', lastname']),
findPerson,
normalize,
trim);
addToTable(personId);
16
First, you need to understand…
• The issue with side effects and mutations
• Singularity principle
• Currying and composition
• Functors and Monads
Side effects
doWork doMoreWork
sharedData = [...]
depends on updatechanges
coupling
1 2
order matters
function addToTable(personId) {
if(personId != null) {
personId = studentId.replace(/^s*|-|s*$/g,'');
if(personId.length !== 9) {
throw new Error('Invalid Input');
}
var person = db.get(personId);
if (person) {
var rowInfo =
`<td>${person.ssn}</td>
<td>${person.firstname}</td>
<td>${person.lastname}</td>`;
$(`#${tableId}
tr:last`).after(`<tr>${rowInfo}</tr>`);
return $(`#${tableId} tr`).length - 1;
}
else {
throw new Error(’Person Record not found!');
}
}
else {
return 0;
}
}
External
Dependencies
Complexity
IO
How do we deal with
mutations?
Lenses: object mutations
const person = new Person('Alonzo', 'Church');
const lastnameLens = lenseProp('lastName');
view(lastnameLens, person); //-> 'Church'
const newPerson = set(lastnameLens,
'Mourning', person);
newPerson.lastname; //-> 'Mourning’
person.lastname; //-> 'Church'
var person = {
firstname:'Alonzo’,
lastname: 'Church'
}
Singular Functions
• Singularity principle: functions are supposed
to perform only one task
• Simple functions typically have fewer
arguments (reduced arity) than complex
functions
• Simple functions are easy to test, but also
composeable and chainable
Currying
• Some functions can’t be reduced to single arguments
• Used to partially evaluate a function as a sequence of
steps by providing arguments one-at-a-time
• Currying enables the composition of complex
functions
function f(a, b, c) { … }
f a f(a, undefined, undefined)
evaluating: returns:
( )
function f(a, b, c) { … }
f(a, b, c) {
return function (a) {
return function (b) {
return function (c) {
…
}
}
}
}
Currying2
f a f(b, c)
Evaluating:
f a f(c)b
f a resultb c
returns:
(
(
(
)
)
)
Currying3
Currying Example
var name = curry2(function (first, last) {
return [last, first].join(',');
});
name('Haskell'); //-> Function
name('Haskell')('Curry'); //-> 'Curry, Haskell'
Composition
• Loosely couple a function’s return value
with another function’s arguments
(pipeline)
• Separates a program’s description from
evaluation
• The resulf of composing a function is
another function that can be composed
further
Composition2
f•g(x) = f(g(x))
Composition example
var str = `A complex system that works is invariably
found to have evolved from a simple system that
worked`;
var explode = str => str.split(/s+/);
var count = arr => arr.length;
var countWords = compose(count, explode);
countWords(str); // -> 17
Composition is the backbone of
modularity in FP
function addToTable(personId) {
if(personId != null) {
personId = studentId.replace(/^s*|-|s*$/g, '');
if(personId.length !== 9) {
throw new Error('Invalid Input');
}
var person = db.get(personId);
if (person) {
var rowInfo =
`<td>${person.ssn}</td>
<td>${person.firstname}</td>
<td>${person.lastname}</td>`;
$(`#${tableId}
tr:last`).after(`<tr>${rowInfo}</tr>`);
return $(`#${tableId} tr`).length - 1;
}
else {
throw new Error('Person Record not found!');
}
}
...
Breaking monolithic functions
addToTable
cleanInput
checkLengthSsn
findPerson
populateRow
appendToTable
✔
✔
✔
Impure:
can’t be tested
reliably

Decompose => Compose
Become the building blocks of your program
Building blocks
const safeFindObject = curry(function (db, id) {
return Maybe.fromNullable(db.get(id));
});
const findPerson = safeFindObject(DB('people'));
const trim = (str) => str.replace(/^s*|s*$/g, '');
const normalize = (str) => str.replace(/-/g, '');
Building blocks2
const populateRow = function (columns) {
const cell_t = template('<td><%= a %></td>');
const row_t = template('<tr><%= a %></tr>');
const obj = function (a) {
return {'a': a};
};
const row = compose(
row_t, obj, join(''),
map(cell_t),
map(obj));
return row(columns);
};
const addToTable = curry(
function (elementId, rowInfo) {
$(`#${elementId} tr:last`)
.after(`<tr>${rowInfo}</tr>`);
return $(`#${elementId} tr`).length - 1;
});
const addToTable = compose(
appendToTable('personTable'),
populateRow,
props(['ssn','firstname’,'lastname']),
findPerson,
normalize,
trim);
addToTable(personId);
35
Functional programming
But what about errors?
Containerizing
37
const Wrapper = function (val) {
this._val = val;
};
// Map
Wrapper.prototype.map = function (f) {
return f(this._val);
};
// Unit
const wrap = (val) => new Wrapper(val);
guarded
identity
map
identity returns
the same value
Wrapper
Containerizing2
const wrappedValue = wrap('Get Functional');
// extract the value
const value =
wrappedValue.map(toUpper).map(repeat(2)).map(identity);
value; //-> 'GET FUNCTIONAL GET FUNCTIONAL'
• Data structure that can be mapped over
• Lift values into a container so that you can apply
functions onto them, place the result back into the
container
Functors: next level containers
39
// Functor
Wrapper.prototype.fmap = function (f) {
return wrap(f(this._val));
};
Functors2
40
const plus = curry((a, b) => a + b);
conts plus3 = plus(3);
const two = wrap(2);
const five = two.fmap(plus3); //-> Wrapper(5)
two.fmap(plus3).fmap(plus10); //-> Wrapper(15)
plus3
fmap
Wrapper
2
Wrapper
2
apply function
Wrapper
5
wrap
What can we do with containers?
41
Wrap a potentially null value or
a function that can cause the
program to fail
Software is unpredictable
42
Exception thrown
but contained
within the wrapper
Exception does not
affect any other
part of the system
Software must be robust
43
Function throws an
exception
Exception is propagated and gracefully
handled
program flow
Monads
44
Functor + Unit = Monad
…and some more
Monads2
45
• Backbone of functional
programming
• Treat data and operations
algebraically
• Data type used for applying a
sequence of transformations on
data (conveyor belt model)
• Abstract data flows
• Used for error handling, IO,
Logging, etc
So call me: Maybe
46
• Wall-off impurity
• Consolidate null-check logic
• Consolidated exception throwing
• Support compositionally of functions
• Centralize logic for providing default values
Maybe Monad
47
Just
object
Nothing
Maybe
Just(value): represents a
container that wraps a
defined value.
Nothing(): represents a
container that has no value,
or a failure that needs no
additional information.
Maybe: Just
48
class Maybe {
static fromNullable(a) {
return a !== null ?
just(a) : nothing();
}
static of(a) {
return just(a);
}
}
class Just extends Maybe {
map(f) {
return
of(f(this.value));
}
getOrElse() {
return this.value;
}
}
Maybe: Nothing
49
class Nothing extends Maybe {
map(f) {
return this; // noop
}
get value() {
throw new TypeError(`Can't extract
the value of a Nothing.`);
}
getOrElse(other) {
return other;
}
}
Usage
50
Maybe.of(3).map(plus2);
//-> Maybe(5)
Maybe.of(3).chain(plus2);
//-> 5
Maybe.fromNullable(null).map(plus2);
//-> Nothing()
Remove nested code
51
function getCountry(student) {
var school = student.school();
if (school !== null ) {
var addr = school.address();
if (addr !== null ) {
return addr.country();
}
}
return 'Country does not exist!';
}
student; //-> Maybe<Student>
const getCountry = student => student
.map(prop('school'))
.map(prop('address'))
.map(prop('country'))
.getOrElse('Country does not
exist!');
Monads abstract data flow
+ Error Handling
52
trimxxx-xxx id normalize id findPerson
addToTable(personId)
nullpopulateRow
Left
null
Left
appendToTable
orElse console.log
skipped skipped
props
skipped
When an error occurs, Maybe safely propagates
the error through the components of your code
To recap
function addToTable(personId) {
if(personId!= null) {
personId= personId (/^s*|-|s*$/g, '');
if(personId!== 9) {
throw new Error('Invalid Input');
}
var person= db.get(personId);
if (person) {
var rowInfo =
`<td>${person.ssn}</td>
<td>${person.firstname}</td>
<td>${person.lastname}</td>`;
$(`#${tableId}
tr:last`).after(`<tr>${rowInfo}</tr>`);
return $(`#${tableId} tr`).length - 1;
}
else {
throw new Error(’Person not found!');
}
}
else {
return 0;
}
}
From
imperative
To Functional
const addToTable = compose(
appendToTable('personTable'),
populateRow,
props(['ssn','firstname','lastname']),
findPerson,
normalize,
trim);
addToTable('444-44-4444'); //-> Maybe(Student)
addToTable('xxx-xx-xxxx'); //-> Maybe(null)
addToTable('xxx-xx-xxxx').orElse(
console.log('Error adding student');
);
55
Thinking this way will…
• Allow you create modular, testable, reliable,
and robust applications
• Decompose, decompose, decompose!
• Pure functions: help design for concurrency
• Enable other paradigms:
– Reactive programming
– Concurrent programming
– Immutable architectures?
My way of contributing and
teaching
Magazines
https://dzone.com/refcardz/functional-programming-with-javascript
Functional
Programming in
JavaScript
www.manning.com/atencio
Functional
PHP
https://leanpub.com/functional-php
Free!
@luijar
https://legacy.joind.in/16810
Thanks!

More Related Content

PDF
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
PDF
Intro to Functional Programming
PPTX
Functional programming in JavaScript
PPTX
Functional Programming with JavaScript
PDF
Functional Programming with JavaScript
PPTX
Category theory, Monads, and Duality in the world of (BIG) Data
PDF
Scala introduction
PPTX
Introduction to java 8 stream api
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
Intro to Functional Programming
Functional programming in JavaScript
Functional Programming with JavaScript
Functional Programming with JavaScript
Category theory, Monads, and Duality in the world of (BIG) Data
Scala introduction
Introduction to java 8 stream api

What's hot (20)

PDF
EcmaScript 6 - The future is here
PPTX
Type Driven Development with TypeScript
ODP
JavaScript Web Development
PDF
Pragmatic Real-World Scala (short version)
PDF
Being functional in PHP (DPC 2016)
PPTX
Fun with Lambdas: C++14 Style (part 2)
PDF
ES6 - Next Generation Javascript
PDF
jq: JSON - Like a Boss
PDF
Java 8 Stream API. A different way to process collections.
PDF
ADG Poznań - Kotlin for Android developers
PDF
Introduction to JQ
PPTX
Joy of scala
PDF
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
PPTX
FunctionalJS - George Shevtsov
PDF
JavaScript 2016 for C# Developers
PPT
Java 8 Streams
PDF
RESTful API using scalaz (3)
PDF
An Intro To ES6
PDF
Anonymous functions in JavaScript
PDF
Functional Algebra: Monoids Applied
EcmaScript 6 - The future is here
Type Driven Development with TypeScript
JavaScript Web Development
Pragmatic Real-World Scala (short version)
Being functional in PHP (DPC 2016)
Fun with Lambdas: C++14 Style (part 2)
ES6 - Next Generation Javascript
jq: JSON - Like a Boss
Java 8 Stream API. A different way to process collections.
ADG Poznań - Kotlin for Android developers
Introduction to JQ
Joy of scala
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
FunctionalJS - George Shevtsov
JavaScript 2016 for C# Developers
Java 8 Streams
RESTful API using scalaz (3)
An Intro To ES6
Anonymous functions in JavaScript
Functional Algebra: Monoids Applied
Ad

Similar to Thinking Functionally with JavaScript (20)

PPTX
Functional Programming in JavaScript by Luis Atencio
ODP
Functional programming
PDF
379008-rc217-functionalprogramming
PDF
Introduction to Functional Programming
PDF
Functional Programming with Javascript
PPTX
Functional programming for the Advanced Beginner
PDF
Functional Programming in JavaScript
PDF
Building Functional Islands
PDF
Functional programming techniques in regular JavaScript
PDF
Functional programing in Javascript (lite intro)
PPTX
Functional programming in javascript
PDF
Functional Programming for OO Programmers (part 2)
PDF
Functional Programming Principles & Patterns
PDF
Functional JavaScript Fundamentals
PPTX
Functional Programming in Javascript - IL Tech Talks week
PDF
Christian Gill ''Functional programming for the people''
PPTX
An Introduction to Functional Programming with Javascript
PPTX
Things about Functional JavaScript
PPTX
Why functional programming in C# & F#
PDF
Hardcore functional programming
Functional Programming in JavaScript by Luis Atencio
Functional programming
379008-rc217-functionalprogramming
Introduction to Functional Programming
Functional Programming with Javascript
Functional programming for the Advanced Beginner
Functional Programming in JavaScript
Building Functional Islands
Functional programming techniques in regular JavaScript
Functional programing in Javascript (lite intro)
Functional programming in javascript
Functional Programming for OO Programmers (part 2)
Functional Programming Principles & Patterns
Functional JavaScript Fundamentals
Functional Programming in Javascript - IL Tech Talks week
Christian Gill ''Functional programming for the people''
An Introduction to Functional Programming with Javascript
Things about Functional JavaScript
Why functional programming in C# & F#
Hardcore functional programming
Ad

Recently uploaded (20)

PPTX
Transform Your Business with a Software ERP System
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
How Creative Agencies Leverage Project Management Software.pdf
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
System and Network Administraation Chapter 3
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
L1 - Introduction to python Backend.pptx
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
ISO 45001 Occupational Health and Safety Management System
Transform Your Business with a Software ERP System
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
How Creative Agencies Leverage Project Management Software.pdf
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
How to Migrate SBCGlobal Email to Yahoo Easily
CHAPTER 2 - PM Management and IT Context
Design an Analysis of Algorithms II-SECS-1021-03
Navsoft: AI-Powered Business Solutions & Custom Software Development
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Upgrade and Innovation Strategies for SAP ERP Customers
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
System and Network Administraation Chapter 3
Design an Analysis of Algorithms I-SECS-1021-03
L1 - Introduction to python Backend.pptx
ManageIQ - Sprint 268 Review - Slide Deck
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
Which alternative to Crystal Reports is best for small or large businesses.pdf
ISO 45001 Occupational Health and Safety Management System

Thinking Functionally with JavaScript

  • 1. Thinking Functionally Functional Programming using JavaScript Luis Atencio @luijar Blog: http://luisatencio.net
  • 2. What is FP? “Functional programming refers to the declarative evaluation of pure functions to create immutable programs by avoiding externally observable side effects.”
  • 3. Why? • Reduce complexity • Create code that is easier to trace, debug, and test • Modularize code leads to separation of concerns • Avoid duplications • Implement changes unobtrusively • Create code that is extensible and configurable • Foundation for Rx and reactive programming
  • 4. Why Learn it now? • Most newer languages are/have incorporated functional features into them. – Java (streams, function interfaces, lambda expressions) – Scala (hybrid FP + OO) – F# (immutable structures, pipes) • LINQ – ES6 JavaScript -> ES7 JavaScript will have streams – Clojure, Lisp, Scheme, Haskell, OCaml, Erlang, etc • We live in a highly concurrent world
  • 5. Paradigm shift • Eliminate externally observable side effects • Control (reduce or eliminate) mutations • Write declaratively and point-free • Everything is a value (even functions) • Functions ALWAYS return values • Recursion as looping mechanism (eliminate loops) 5
  • 6. The OO World 6 Data and behavior tightly coupled ClassA data behavior ClassB data behavior ClassC data behavior Unit testing is challenging Unit of work: Classes
  • 7. function doWork(objectA): objectB The FP World function doMoreWork(objectB): objectC function displayResults(objectC) Data and behavior loosely coupled Unit testing is (basically) free Unit of work: Function
  • 8. Is JavaScript functional? JavaScript is a dynamic, object-oriented programing language whose expressive power via closures and high-order functions makes it compelling for writing in a functional style. Features that favor functional programming: • const keyword • Promises • Lambda expressions + closures • Generators and Iterators • FP libraries (Ramda.js, Underscore.js, Lodash.js, etc)
  • 9. Hello World! document.getElementById('msg').innerHTML = '<h1>Hello World</h1>'; compose(addToDom('#msg'), h1)('Hello World'); vs
  • 10. More functional Hello World! compose ( addToDom('#msg'), h2, repeat(3))('Hello World'); Declarative & configurable
  • 11. Even more functional Hello World! compose ( addToDom('#msg'), h2, repeat(3), escapeChars)('Hello World'); Extensible
  • 12. Declarative Programming • Describe WHAT a program does • Not HOW to do it SQL> SELECT firstname, birthYear FROM Person WHERE year > 1903 AND country = 'US' GROUP BY firstname, birthYear FP> compose(select(firstname, birthYear), from('Person'), where(year => year === 1903), where(country => country === 'US'), groupBy(firstname, birthYear))(query);
  • 13. First let’s look at the current state of things Imperative Programming
  • 14. function addToTable(personId) { if(personId != null) { personId = studentId.replace(/^s*|-|s*$/g, ''); if(personId.length !== 9) { throw new Error('Invalid Input'); } var person = db.get(personId); if (person) { var rowInfo = `<td>${person.ssn}</td> <td>${person.firstname}</td> <td>${person.lastname}</td>`; $(`#${tableId} tr:last`).after(`<tr>${rowInfo}</tr>`); return $(`#${tableId} tr`).length - 1; } else { throw new Error('Person Record not found!'); } } else { return 0; } }
  • 15. … after thinking functionally… …and some magic…
  • 16. var addToTable = compose( appendToTable(’personTable'), populateRow, props(['ssn', 'firstname', lastname']), findPerson, normalize, trim); addToTable(personId); 16
  • 17. First, you need to understand… • The issue with side effects and mutations • Singularity principle • Currying and composition • Functors and Monads
  • 18. Side effects doWork doMoreWork sharedData = [...] depends on updatechanges coupling 1 2 order matters
  • 19. function addToTable(personId) { if(personId != null) { personId = studentId.replace(/^s*|-|s*$/g,''); if(personId.length !== 9) { throw new Error('Invalid Input'); } var person = db.get(personId); if (person) { var rowInfo = `<td>${person.ssn}</td> <td>${person.firstname}</td> <td>${person.lastname}</td>`; $(`#${tableId} tr:last`).after(`<tr>${rowInfo}</tr>`); return $(`#${tableId} tr`).length - 1; } else { throw new Error(’Person Record not found!'); } } else { return 0; } } External Dependencies Complexity IO
  • 20. How do we deal with mutations?
  • 21. Lenses: object mutations const person = new Person('Alonzo', 'Church'); const lastnameLens = lenseProp('lastName'); view(lastnameLens, person); //-> 'Church' const newPerson = set(lastnameLens, 'Mourning', person); newPerson.lastname; //-> 'Mourning’ person.lastname; //-> 'Church' var person = { firstname:'Alonzo’, lastname: 'Church' }
  • 22. Singular Functions • Singularity principle: functions are supposed to perform only one task • Simple functions typically have fewer arguments (reduced arity) than complex functions • Simple functions are easy to test, but also composeable and chainable
  • 23. Currying • Some functions can’t be reduced to single arguments • Used to partially evaluate a function as a sequence of steps by providing arguments one-at-a-time • Currying enables the composition of complex functions function f(a, b, c) { … } f a f(a, undefined, undefined) evaluating: returns: ( )
  • 24. function f(a, b, c) { … } f(a, b, c) { return function (a) { return function (b) { return function (c) { … } } } } Currying2
  • 25. f a f(b, c) Evaluating: f a f(c)b f a resultb c returns: ( ( ( ) ) ) Currying3
  • 26. Currying Example var name = curry2(function (first, last) { return [last, first].join(','); }); name('Haskell'); //-> Function name('Haskell')('Curry'); //-> 'Curry, Haskell'
  • 27. Composition • Loosely couple a function’s return value with another function’s arguments (pipeline) • Separates a program’s description from evaluation • The resulf of composing a function is another function that can be composed further
  • 29. Composition example var str = `A complex system that works is invariably found to have evolved from a simple system that worked`; var explode = str => str.split(/s+/); var count = arr => arr.length; var countWords = compose(count, explode); countWords(str); // -> 17
  • 30. Composition is the backbone of modularity in FP
  • 31. function addToTable(personId) { if(personId != null) { personId = studentId.replace(/^s*|-|s*$/g, ''); if(personId.length !== 9) { throw new Error('Invalid Input'); } var person = db.get(personId); if (person) { var rowInfo = `<td>${person.ssn}</td> <td>${person.firstname}</td> <td>${person.lastname}</td>`; $(`#${tableId} tr:last`).after(`<tr>${rowInfo}</tr>`); return $(`#${tableId} tr`).length - 1; } else { throw new Error('Person Record not found!'); } } ... Breaking monolithic functions
  • 33. Building blocks const safeFindObject = curry(function (db, id) { return Maybe.fromNullable(db.get(id)); }); const findPerson = safeFindObject(DB('people')); const trim = (str) => str.replace(/^s*|s*$/g, ''); const normalize = (str) => str.replace(/-/g, '');
  • 34. Building blocks2 const populateRow = function (columns) { const cell_t = template('<td><%= a %></td>'); const row_t = template('<tr><%= a %></tr>'); const obj = function (a) { return {'a': a}; }; const row = compose( row_t, obj, join(''), map(cell_t), map(obj)); return row(columns); }; const addToTable = curry( function (elementId, rowInfo) { $(`#${elementId} tr:last`) .after(`<tr>${rowInfo}</tr>`); return $(`#${elementId} tr`).length - 1; });
  • 35. const addToTable = compose( appendToTable('personTable'), populateRow, props(['ssn','firstname’,'lastname']), findPerson, normalize, trim); addToTable(personId); 35 Functional programming
  • 36. But what about errors?
  • 37. Containerizing 37 const Wrapper = function (val) { this._val = val; }; // Map Wrapper.prototype.map = function (f) { return f(this._val); }; // Unit const wrap = (val) => new Wrapper(val); guarded identity map identity returns the same value Wrapper
  • 38. Containerizing2 const wrappedValue = wrap('Get Functional'); // extract the value const value = wrappedValue.map(toUpper).map(repeat(2)).map(identity); value; //-> 'GET FUNCTIONAL GET FUNCTIONAL'
  • 39. • Data structure that can be mapped over • Lift values into a container so that you can apply functions onto them, place the result back into the container Functors: next level containers 39 // Functor Wrapper.prototype.fmap = function (f) { return wrap(f(this._val)); };
  • 40. Functors2 40 const plus = curry((a, b) => a + b); conts plus3 = plus(3); const two = wrap(2); const five = two.fmap(plus3); //-> Wrapper(5) two.fmap(plus3).fmap(plus10); //-> Wrapper(15) plus3 fmap Wrapper 2 Wrapper 2 apply function Wrapper 5 wrap
  • 41. What can we do with containers? 41 Wrap a potentially null value or a function that can cause the program to fail
  • 42. Software is unpredictable 42 Exception thrown but contained within the wrapper Exception does not affect any other part of the system
  • 43. Software must be robust 43 Function throws an exception Exception is propagated and gracefully handled program flow
  • 44. Monads 44 Functor + Unit = Monad …and some more
  • 45. Monads2 45 • Backbone of functional programming • Treat data and operations algebraically • Data type used for applying a sequence of transformations on data (conveyor belt model) • Abstract data flows • Used for error handling, IO, Logging, etc
  • 46. So call me: Maybe 46 • Wall-off impurity • Consolidate null-check logic • Consolidated exception throwing • Support compositionally of functions • Centralize logic for providing default values
  • 47. Maybe Monad 47 Just object Nothing Maybe Just(value): represents a container that wraps a defined value. Nothing(): represents a container that has no value, or a failure that needs no additional information.
  • 48. Maybe: Just 48 class Maybe { static fromNullable(a) { return a !== null ? just(a) : nothing(); } static of(a) { return just(a); } } class Just extends Maybe { map(f) { return of(f(this.value)); } getOrElse() { return this.value; } }
  • 49. Maybe: Nothing 49 class Nothing extends Maybe { map(f) { return this; // noop } get value() { throw new TypeError(`Can't extract the value of a Nothing.`); } getOrElse(other) { return other; } }
  • 51. Remove nested code 51 function getCountry(student) { var school = student.school(); if (school !== null ) { var addr = school.address(); if (addr !== null ) { return addr.country(); } } return 'Country does not exist!'; } student; //-> Maybe<Student> const getCountry = student => student .map(prop('school')) .map(prop('address')) .map(prop('country')) .getOrElse('Country does not exist!');
  • 52. Monads abstract data flow + Error Handling 52 trimxxx-xxx id normalize id findPerson addToTable(personId) nullpopulateRow Left null Left appendToTable orElse console.log skipped skipped props skipped When an error occurs, Maybe safely propagates the error through the components of your code
  • 54. function addToTable(personId) { if(personId!= null) { personId= personId (/^s*|-|s*$/g, ''); if(personId!== 9) { throw new Error('Invalid Input'); } var person= db.get(personId); if (person) { var rowInfo = `<td>${person.ssn}</td> <td>${person.firstname}</td> <td>${person.lastname}</td>`; $(`#${tableId} tr:last`).after(`<tr>${rowInfo}</tr>`); return $(`#${tableId} tr`).length - 1; } else { throw new Error(’Person not found!'); } } else { return 0; } } From imperative
  • 55. To Functional const addToTable = compose( appendToTable('personTable'), populateRow, props(['ssn','firstname','lastname']), findPerson, normalize, trim); addToTable('444-44-4444'); //-> Maybe(Student) addToTable('xxx-xx-xxxx'); //-> Maybe(null) addToTable('xxx-xx-xxxx').orElse( console.log('Error adding student'); ); 55
  • 56. Thinking this way will… • Allow you create modular, testable, reliable, and robust applications • Decompose, decompose, decompose! • Pure functions: help design for concurrency • Enable other paradigms: – Reactive programming – Concurrent programming – Immutable architectures?
  • 57. My way of contributing and teaching

Editor's Notes

  • #19: Changing a variable, property or data structure globally Changing the original value of a function’s argument Processing user input Throwing an exception, unless it’s caught within the same function Printing to the screen or logging Querying the DOM or databases
  • #30: John Gall : The Systems Bible
  • #37: Handle with the same elegance? Error handling tends to be very messy with try/catch statements
  • #51: Chain -> also known as flatMap
  • #54: Handle with the same elegance? Error handling tends to be very messy with try/catch statements