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

What's hot (20)

EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
Sebastiano Armeli
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
Garth Gilmour
 
JavaScript Web Development
JavaScript Web DevelopmentJavaScript Web Development
JavaScript Web Development
vito jeng
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
David de Boer
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
Sumant Tambe
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
RameshNair6
 
jq: JSON - Like a Boss
jq: JSON - Like a Bossjq: JSON - Like a Boss
jq: JSON - Like a Boss
Bob Tiernay
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
David Gómez García
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
Bartosz Kosarzycki
 
Introduction to JQ
Introduction to JQIntroduction to JQ
Introduction to JQ
Knoldus Inc.
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
Maxim Novak
 
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Susan Potter
 
FunctionalJS - George Shevtsov
FunctionalJS - George ShevtsovFunctionalJS - George Shevtsov
FunctionalJS - George Shevtsov
Georgiy Shevtsov
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
Rick Beerendonk
 
Java 8 Streams
Java 8 StreamsJava 8 Streams
Java 8 Streams
Manvendra Singh
 
RESTful API using scalaz (3)
RESTful API using scalaz (3)RESTful API using scalaz (3)
RESTful API using scalaz (3)
Yeshwanth Kumar
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
FITC
 
Anonymous functions in JavaScript
Anonymous functions in JavaScriptAnonymous functions in JavaScript
Anonymous functions in JavaScript
Mohammed Sazid Al Rashid
 
Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids Applied
Susan Potter
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
Sebastiano Armeli
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
Garth Gilmour
 
JavaScript Web Development
JavaScript Web DevelopmentJavaScript Web Development
JavaScript Web Development
vito jeng
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
David de Boer
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
Sumant Tambe
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
RameshNair6
 
jq: JSON - Like a Boss
jq: JSON - Like a Bossjq: JSON - Like a Boss
jq: JSON - Like a Boss
Bob Tiernay
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
David Gómez García
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
Bartosz Kosarzycki
 
Introduction to JQ
Introduction to JQIntroduction to JQ
Introduction to JQ
Knoldus Inc.
 
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Susan Potter
 
FunctionalJS - George Shevtsov
FunctionalJS - George ShevtsovFunctionalJS - George Shevtsov
FunctionalJS - George Shevtsov
Georgiy Shevtsov
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
Rick Beerendonk
 
RESTful API using scalaz (3)
RESTful API using scalaz (3)RESTful API using scalaz (3)
RESTful API using scalaz (3)
Yeshwanth Kumar
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
FITC
 
Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids Applied
Susan Potter
 

Similar to Thinking Functionally with JavaScript (20)

Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
Luis Atencio
 
Functional programming
Functional programmingFunctional programming
Functional programming
S M Asaduzzaman
 
379008-rc217-functionalprogramming
379008-rc217-functionalprogramming379008-rc217-functionalprogramming
379008-rc217-functionalprogramming
Luis Atencio
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional Programming
Hoàng Lâm Huỳnh
 
Functional Programming with Javascript
Functional Programming with JavascriptFunctional Programming with Javascript
Functional Programming with Javascript
Deepankar Chopra
 
Functional programming for the Advanced Beginner
Functional programming for the Advanced BeginnerFunctional programming for the Advanced Beginner
Functional programming for the Advanced Beginner
Luis Atencio
 
Functional Programming in JavaScript
Functional Programming in JavaScriptFunctional Programming in JavaScript
Functional Programming in JavaScript
Will Livengood
 
Building Functional Islands
Building Functional IslandsBuilding Functional Islands
Building Functional Islands
Mark Jones
 
Functional programming techniques in regular JavaScript
Functional programming techniques in regular JavaScriptFunctional programming techniques in regular JavaScript
Functional programming techniques in regular JavaScript
Pavel Klimiankou
 
Functional programing in Javascript (lite intro)
Functional programing in Javascript (lite intro)Functional programing in Javascript (lite intro)
Functional programing in Javascript (lite intro)
Nikos Kalogridis
 
Functional programming in javascript
Functional programming in javascriptFunctional programming in javascript
Functional programming in javascript
Boris Burdiliak
 
Functional Programming for OO Programmers (part 2)
Functional Programming for OO Programmers (part 2)Functional Programming for OO Programmers (part 2)
Functional Programming for OO Programmers (part 2)
Calvin Cheng
 
Functional Programming Principles & Patterns
Functional Programming Principles & PatternsFunctional Programming Principles & Patterns
Functional Programming Principles & Patterns
zupzup.org
 
Functional JavaScript Fundamentals
Functional JavaScript FundamentalsFunctional JavaScript Fundamentals
Functional JavaScript Fundamentals
Srdjan Strbanovic
 
Functional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekFunctional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks week
yoavrubin
 
Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''
OdessaJS Conf
 
An Introduction to Functional Programming with Javascript
An Introduction to Functional Programming with JavascriptAn Introduction to Functional Programming with Javascript
An Introduction to Functional Programming with Javascript
Doug Sparling
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
ChengHui Weng
 
Why functional programming in C# & F#
Why functional programming in C# & F#Why functional programming in C# & F#
Why functional programming in C# & F#
Riccardo Terrell
 
Hardcore functional programming
Hardcore functional programmingHardcore functional programming
Hardcore functional programming
Leonardo Andres Garcia Crespo
 
Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
Luis Atencio
 
379008-rc217-functionalprogramming
379008-rc217-functionalprogramming379008-rc217-functionalprogramming
379008-rc217-functionalprogramming
Luis Atencio
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional Programming
Hoàng Lâm Huỳnh
 
Functional Programming with Javascript
Functional Programming with JavascriptFunctional Programming with Javascript
Functional Programming with Javascript
Deepankar Chopra
 
Functional programming for the Advanced Beginner
Functional programming for the Advanced BeginnerFunctional programming for the Advanced Beginner
Functional programming for the Advanced Beginner
Luis Atencio
 
Functional Programming in JavaScript
Functional Programming in JavaScriptFunctional Programming in JavaScript
Functional Programming in JavaScript
Will Livengood
 
Building Functional Islands
Building Functional IslandsBuilding Functional Islands
Building Functional Islands
Mark Jones
 
Functional programming techniques in regular JavaScript
Functional programming techniques in regular JavaScriptFunctional programming techniques in regular JavaScript
Functional programming techniques in regular JavaScript
Pavel Klimiankou
 
Functional programing in Javascript (lite intro)
Functional programing in Javascript (lite intro)Functional programing in Javascript (lite intro)
Functional programing in Javascript (lite intro)
Nikos Kalogridis
 
Functional programming in javascript
Functional programming in javascriptFunctional programming in javascript
Functional programming in javascript
Boris Burdiliak
 
Functional Programming for OO Programmers (part 2)
Functional Programming for OO Programmers (part 2)Functional Programming for OO Programmers (part 2)
Functional Programming for OO Programmers (part 2)
Calvin Cheng
 
Functional Programming Principles & Patterns
Functional Programming Principles & PatternsFunctional Programming Principles & Patterns
Functional Programming Principles & Patterns
zupzup.org
 
Functional JavaScript Fundamentals
Functional JavaScript FundamentalsFunctional JavaScript Fundamentals
Functional JavaScript Fundamentals
Srdjan Strbanovic
 
Functional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekFunctional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks week
yoavrubin
 
Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''
OdessaJS Conf
 
An Introduction to Functional Programming with Javascript
An Introduction to Functional Programming with JavascriptAn Introduction to Functional Programming with Javascript
An Introduction to Functional Programming with Javascript
Doug Sparling
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
ChengHui Weng
 
Why functional programming in C# & F#
Why functional programming in C# & F#Why functional programming in C# & F#
Why functional programming in C# & F#
Riccardo Terrell
 
Ad

Recently uploaded (20)

ICDL FULL STANDARD 2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdf
ICDL FULL STANDARD  2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdfICDL FULL STANDARD  2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdf
ICDL FULL STANDARD 2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdf
M. Luisetto Pharm.D.Spec. Pharmacology
 
Agentic AI Desgin Principles in five slides.pptx
Agentic AI Desgin Principles in five slides.pptxAgentic AI Desgin Principles in five slides.pptx
Agentic AI Desgin Principles in five slides.pptx
MOSIUOA WESI
 
Risk Management in Software Projects: Identifying, Analyzing, and Controlling...
Risk Management in Software Projects: Identifying, Analyzing, and Controlling...Risk Management in Software Projects: Identifying, Analyzing, and Controlling...
Risk Management in Software Projects: Identifying, Analyzing, and Controlling...
gauravvmanchandaa200
 
War Story: Removing Offensive Language from Percona Toolkit
War Story: Removing Offensive Language from Percona ToolkitWar Story: Removing Offensive Language from Percona Toolkit
War Story: Removing Offensive Language from Percona Toolkit
Sveta Smirnova
 
Custom Software Development: Types, Applications and Benefits.pdf
Custom Software Development: Types, Applications and Benefits.pdfCustom Software Development: Types, Applications and Benefits.pdf
Custom Software Development: Types, Applications and Benefits.pdf
Digital Aptech
 
Autoposting.ai Sales Deck - Skyrocket your LinkedIn's ROI
Autoposting.ai Sales Deck - Skyrocket your LinkedIn's ROIAutoposting.ai Sales Deck - Skyrocket your LinkedIn's ROI
Autoposting.ai Sales Deck - Skyrocket your LinkedIn's ROI
Udit Goenka
 
Software Risk and Quality management.pptx
Software Risk and Quality management.pptxSoftware Risk and Quality management.pptx
Software Risk and Quality management.pptx
HassanBangash9
 
Optimising Claims Management with Claims Processing Systems
Optimising Claims Management with Claims Processing SystemsOptimising Claims Management with Claims Processing Systems
Optimising Claims Management with Claims Processing Systems
Insurance Tech Services
 
Intranet Examples That Are Changing the Way We Work
Intranet Examples That Are Changing the Way We WorkIntranet Examples That Are Changing the Way We Work
Intranet Examples That Are Changing the Way We Work
BizPortals Solutions
 
SQL-COMMANDS instructionsssssssssss.pptx
SQL-COMMANDS instructionsssssssssss.pptxSQL-COMMANDS instructionsssssssssss.pptx
SQL-COMMANDS instructionsssssssssss.pptx
Ashlei5
 
aswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjar
aswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjaraswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjar
aswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjar
muhammadalikhanalikh1
 
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdfBoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
Ortus Solutions, Corp
 
Oliveira2024 - Combining GPT and Weak Supervision.pdf
Oliveira2024 - Combining GPT and Weak Supervision.pdfOliveira2024 - Combining GPT and Weak Supervision.pdf
Oliveira2024 - Combining GPT and Weak Supervision.pdf
GiliardGodoi1
 
Marketing And Sales Software Services.pptx
Marketing And Sales Software Services.pptxMarketing And Sales Software Services.pptx
Marketing And Sales Software Services.pptx
julia smits
 
AI Alternative - Discover the best AI tools and their alternatives
AI Alternative - Discover the best AI tools and their alternativesAI Alternative - Discover the best AI tools and their alternatives
AI Alternative - Discover the best AI tools and their alternatives
AI Alternative
 
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptxHow AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
kalichargn70th171
 
Boost Student Engagement with Smart Attendance Software for Schools
Boost Student Engagement with Smart Attendance Software for SchoolsBoost Student Engagement with Smart Attendance Software for Schools
Boost Student Engagement with Smart Attendance Software for Schools
Visitu
 
Techdebt handling with cleancode focus and as risk taker
Techdebt handling with cleancode focus and as risk takerTechdebt handling with cleancode focus and as risk taker
Techdebt handling with cleancode focus and as risk taker
RajaNagendraKumar
 
How to Generate Financial Statements in QuickBooks Like a Pro (1).pdf
How to Generate Financial Statements in QuickBooks Like a Pro (1).pdfHow to Generate Financial Statements in QuickBooks Like a Pro (1).pdf
How to Generate Financial Statements in QuickBooks Like a Pro (1).pdf
QuickBooks Training
 
Rebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core FoundationRebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core Foundation
Cadabra Studio
 
ICDL FULL STANDARD 2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdf
ICDL FULL STANDARD  2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdfICDL FULL STANDARD  2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdf
ICDL FULL STANDARD 2025 Luisetto mauro - Academia domani- 55 HOURS LONG pdf
M. Luisetto Pharm.D.Spec. Pharmacology
 
Agentic AI Desgin Principles in five slides.pptx
Agentic AI Desgin Principles in five slides.pptxAgentic AI Desgin Principles in five slides.pptx
Agentic AI Desgin Principles in five slides.pptx
MOSIUOA WESI
 
Risk Management in Software Projects: Identifying, Analyzing, and Controlling...
Risk Management in Software Projects: Identifying, Analyzing, and Controlling...Risk Management in Software Projects: Identifying, Analyzing, and Controlling...
Risk Management in Software Projects: Identifying, Analyzing, and Controlling...
gauravvmanchandaa200
 
War Story: Removing Offensive Language from Percona Toolkit
War Story: Removing Offensive Language from Percona ToolkitWar Story: Removing Offensive Language from Percona Toolkit
War Story: Removing Offensive Language from Percona Toolkit
Sveta Smirnova
 
Custom Software Development: Types, Applications and Benefits.pdf
Custom Software Development: Types, Applications and Benefits.pdfCustom Software Development: Types, Applications and Benefits.pdf
Custom Software Development: Types, Applications and Benefits.pdf
Digital Aptech
 
Autoposting.ai Sales Deck - Skyrocket your LinkedIn's ROI
Autoposting.ai Sales Deck - Skyrocket your LinkedIn's ROIAutoposting.ai Sales Deck - Skyrocket your LinkedIn's ROI
Autoposting.ai Sales Deck - Skyrocket your LinkedIn's ROI
Udit Goenka
 
Software Risk and Quality management.pptx
Software Risk and Quality management.pptxSoftware Risk and Quality management.pptx
Software Risk and Quality management.pptx
HassanBangash9
 
Optimising Claims Management with Claims Processing Systems
Optimising Claims Management with Claims Processing SystemsOptimising Claims Management with Claims Processing Systems
Optimising Claims Management with Claims Processing Systems
Insurance Tech Services
 
Intranet Examples That Are Changing the Way We Work
Intranet Examples That Are Changing the Way We WorkIntranet Examples That Are Changing the Way We Work
Intranet Examples That Are Changing the Way We Work
BizPortals Solutions
 
SQL-COMMANDS instructionsssssssssss.pptx
SQL-COMMANDS instructionsssssssssss.pptxSQL-COMMANDS instructionsssssssssss.pptx
SQL-COMMANDS instructionsssssssssss.pptx
Ashlei5
 
aswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjar
aswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjaraswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjar
aswjkdwelhjdfshlfjkhewljhfljawerhwjarhwjkahrjar
muhammadalikhanalikh1
 
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdfBoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
Ortus Solutions, Corp
 
Oliveira2024 - Combining GPT and Weak Supervision.pdf
Oliveira2024 - Combining GPT and Weak Supervision.pdfOliveira2024 - Combining GPT and Weak Supervision.pdf
Oliveira2024 - Combining GPT and Weak Supervision.pdf
GiliardGodoi1
 
Marketing And Sales Software Services.pptx
Marketing And Sales Software Services.pptxMarketing And Sales Software Services.pptx
Marketing And Sales Software Services.pptx
julia smits
 
AI Alternative - Discover the best AI tools and their alternatives
AI Alternative - Discover the best AI tools and their alternativesAI Alternative - Discover the best AI tools and their alternatives
AI Alternative - Discover the best AI tools and their alternatives
AI Alternative
 
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptxHow AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
kalichargn70th171
 
Boost Student Engagement with Smart Attendance Software for Schools
Boost Student Engagement with Smart Attendance Software for SchoolsBoost Student Engagement with Smart Attendance Software for Schools
Boost Student Engagement with Smart Attendance Software for Schools
Visitu
 
Techdebt handling with cleancode focus and as risk taker
Techdebt handling with cleancode focus and as risk takerTechdebt handling with cleancode focus and as risk taker
Techdebt handling with cleancode focus and as risk taker
RajaNagendraKumar
 
How to Generate Financial Statements in QuickBooks Like a Pro (1).pdf
How to Generate Financial Statements in QuickBooks Like a Pro (1).pdfHow to Generate Financial Statements in QuickBooks Like a Pro (1).pdf
How to Generate Financial Statements in QuickBooks Like a Pro (1).pdf
QuickBooks Training
 
Rebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core FoundationRebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core Foundation
Cadabra Studio
 
Ad

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