SlideShare a Scribd company logo
1 of 76
Download to read offline
Refactoring to
Immutability
@KevlinHenney
Functional programming
Functional programming
typically avoids using
mutable state.
https://wiki.haskell.org/Functional_programming
https://xkcd.com/1270/
Functional programming
combines the flexibility
and power of abstract
mathematics with the
intuitive clarity of
abstract mathematics.
Rien n'est plus
dangereux qu'une
idée, quand on n'a
qu'une idée.
Émile-Auguste Chartier
Nothing is more
dangerous than an
idea, when you
have only one idea.
Émile-Auguste Chartier
String
Asking a question
should not change
the answer.
To keep our C++ API boundary simple, we [...] adopted
one-way data flow. The API consists of methods to
perform fire-and-forget mutations and methods to
compute view models required by specific views.
To keep the code understandable, we write functional
style code converting raw data objects into immutable
view models by default. As we identified performance
bottlenecks through profiling, we added caches to avoid
recomputing unchanged intermediate results.
The resulting functional code is easy to maintain,
without sacrificing performance.
https://code.facebook.com/posts/498597036962415/under-the-hood-building-moments/
Excel is the world's
most popular
functional language
Simon Peyton-Jones
I want code to
be reasonable
As a programmer
I want code to
be reasonable
reasonable
raisonnable
raison
raisonner
As a programmer
I want code to
be reasonable
so that I can
reason about it
A large fraction of the flaws in software development
are due to programmers not fully understanding all
the possible states their code may execute in.
In a multithreaded environment, the lack of
understanding and the resulting problems are
greatly amplified, almost to the point of panic if you
are paying attention.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
The Synchronisation Quadrant
Architecture represents the
significant design decisions
that shape a system, where
significant is measured by
cost of change.
Grady Booch
µονόλιθος
There is a beautiful angel in that block
of marble, and I am going to find it.
All I have to do is to knock off the
outside pieces of marble, and be very
careful not to cut into the angel with
my chisel.
George F Pentecost
"The Angel in the Marble"
Functional
Operational
Developmental
Functional
Operational
Developmental
Nothing is more
dangerous than an
idea, when you
have only one idea.
Émile-Auguste Chartier
Nothing is more
dangerous than
OO, when you have
only one object.
public class Clock
{
public static Clock Instance => ...
public TimeOfDay Now => ...
...
}
public void Example()
{
var now = Clock.Instance.Now;
...
}
public void Example(Clock clock)
{
var now = clock.Now;
...
}
public interface Clock
{
TimeOfDay Now => ...
}
public class ClockImpl : Clock
{
public static Clock Instance => ...
...
}
public interface IClock
{
TimeOfDay Now => ...
}
public class Clock : IClock
{
public static IClock Instance => ...
...
}
public interface IClock
{
TimeOfDay Now => ...
}
public class LocalClock : IClock
{
public static IClock Instance => ...
...
}
public interface Clock
{
TimeOfDay Now => ...
}
public class LocalClock : Clock
{
public static Clock Instance => ...
...
}
public void Example(Func<TimeOfDay> timeOfDay)
{
var now = timeOfDay();
...
}
public void Example(TimeOfDay now)
{
...
}
public class TimeOfDay
{
...
public int Hour
{
get ...
set ...
}
public int Minute
{
get ...
set ...
}
public void NextHour() ...
public void NextMinute() ...
}
public class TimeOfDay
{
private int minutes;
public const int minutesInHour = 60;
public const int hoursInDay = 24;
public const int minutesInDay = hoursInDay * minutesInHour;
private static int Wrap(int minutes)
{
return minutes % minutesInDay;
}
public int Hour
{
get
{
return minutes / minutesInHour;
}
set
{
if (value < 0 || value >= hoursInDay)
throw new ArgumentException();
minutes = Wrap(value * minutesInHour + Minute);
}
}
public int Minute
{
get
{
return minutes % minutesInHour;
}
set
{
if (value < 0 || value >= minutesInHour)
throw new ArgumentException();
minutes = Wrap(Hour * minutesInHour + value);
}
}
public void NextHour()
{
minutes = Wrap(minutes + minutesInHour);
}
public void NextMinute()
{
minutes = Wrap(minutes + 1);
}
}
public class TimeOfDay
{
...
public int Hour
{
get ...
set ...
}
public int Minute
{
get ...
set ...
}
public void NextHour() ...
public void NextMinute() ...
}
public class TimeOfDay
{
...
public int Hour
{
get ...
set ...
}
public int Minute
{
get ...
set ...
}
}
public class TimeOfDay
{
...
public int Hour
{
get ...
}
public int Minute
{
get ...
}
}
public class TimeOfDay
{
...
public int Hour => ...
public int Minute => ...
}
public class TimeOfDay
{
...
public TimeOfDay(int hour, int minute) ...
public int Hour => ...
public int Minute => ...
}
public class TimeOfDay
{
...
public TimeOfDay(int hour, int minute) ...
public int Hour => ...
public int Minute => ...
public TimeOfDay WithHour(int newHour) ...
public TimeOfDay WithMinute(int newMinute) ...
}
public class TimeOfDay
{
...
public TimeOfDay(int hour, int minute) ...
public int Hour => ...
public int Minute => ...
public TimeOfDay WithHour(int newHour) ...
public TimeOfDay WithMinute(int newMinute) ...
public TimeOfDay NextHour() ...
public TimeOfDay NextMinute() ...
}
public class TimeOfDay
{
...
public TimeOfDay(int hour, int minute) ...
public int Hour => ...
public int Minute => ...
public TimeOfDay WithHour(int newHour) ...
public TimeOfDay WithMinute(int newMinute) ...
public TimeOfDay NextHour() ...
public TimeOfDay NextMinute() ...
public class Builder
{
...
}
}
public class TimeOfDay
{
private readonly int minutes;
public const int minutesInHour = 60;
public const int hoursInDay = 24;
public const int minutesInDay = hoursInDay * minutesInHour;
private TimeOfDay(int minutes)
{
this.minutes = minutes % minutesInDay;
}
public TimeOfDay(int hour, int minute)
{
if (hour < 0 || hour >= hoursInDay || minute < 0 || minute >= minutesInHour)
throw new ArgumentException();
minutes = hour * minutesInHour + minute;
}
public int Hour => minutes / minutesInHour;
public int Minute => minutes % minutesInHour;
public TimeOfDay WithHour(int newHour) => new TimeOfDay(newHour, Minute);
public TimeOfDay WithMinute(int newMinute) => new TimeOfDay(Hour, newMinute);
public TimeOfDay NextHour() => new TimeOfDay(minutes + minutesInHour);
public TimeOfDay NextMinute() => new TimeOfDay(minutes + 1);
...
}
try {
Integer.parseInt(time.substring(0, 2));
}
catch (Exception x) {
return false;
}
if (Integer.parseInt(time.substring(0, 2)) > 12) {
return false;
}
...
if (!time.substring(9, 11).equals("AM") &
!time.substring(9, 11).equals("PM")) {
return false;
}
Burk Hufnagel
"Put the Mouse Down and Step Away from the Keyboard"
Burk Hufnagel
"Put the Mouse Down and Step Away from the Keyboard"
return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)");
Je n'ai fait celle-ci plus
longue que parce que je
n'ai pas eu le loisir de la
faire plus courte.
Blaise Pascal
I have made this [letter]
longer than usual
because I have not had
time to make it shorter.
Blaise Pascal
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older?
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.limit(15)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.collect(toList())
// Get the first 15 unique surnames in
// uppercase of the book authors that are 50
// years old or older.
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.limit(15)
.collect(toList())
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older.
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.distinct()
.limit(15)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.collect(toList())
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older.
library.stream()
.map(book -> book.getAuthor())
.distinct()
.filter(author -> author.getAge() >= 50)
.limit(15)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.collect(toList())
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older?
List<Author> authors = new ArrayList<Author>();
for (Book book : library)
{
Author author = book.getAuthor();
if (author.getAge() >= 50)
{
authors.add(author);
if (authors.size() == 15)
break;
}
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older?
List<Author> authors = new ArrayList<Author>();
for (Book book : library)
{
Author author = book.getAuthor();
if (author.getAge() >= 50)
{
authors.add(author);
if (authors.size() == 15)
break;
}
}
List<String> result = new ArrayList<String>();
for(Author author : authors)
{
String name = author.getSurname().toUpperCase();
if (!result.contains(name))
result.add(name);
}
// Get the first 15 unique surnames in
// uppercase of the book authors that are 50
// years old or older.
List<String> result = new ArrayList<String>();
for (Book book : library)
{
Author author = book.getAuthor();
if (author.getAge() >= 50)
{
String name = author.getSurname().toUpperCase();
if (!result.contains(name))
{
result.add(name);
if (result.size() == 15)
break;
}
}
}
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older.
List<Author> authors = new ArrayList<Author>();
for (Book book : library)
{
Author author = book.getAuthor();
if (author.getAge() >= 50 && !authors.contains(author))
{
authors.add(author);
if (authors.size() == 15)
break;
}
}
List<String> result = new ArrayList<String>();
for(Author author : authors)
{
String name = author.getSurname().toUpperCase();
if (!result.contains(name))
result.add(name);
}
Try to leave out the part
that readers tend to skip.
Elmore Leonard
When it is not necessary
to change, it is necessary
not to change.
Lucius Cary

More Related Content

Similar to Refactoring to Immutability

Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsFranco Lombardo
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring frameworkSunghyouk Bae
 
05. Java Loops Methods and Classes
05. Java Loops Methods and Classes05. Java Loops Methods and Classes
05. Java Loops Methods and ClassesIntro C# Book
 
Introduction to functional programming using Ocaml
Introduction to functional programming using OcamlIntroduction to functional programming using Ocaml
Introduction to functional programming using Ocamlpramode_ce
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackNelson Glauber Leal
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Codemotion
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехСбертех | SberTech
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...GeeksLab Odessa
 
OCamlOScope: a New OCaml API Search
OCamlOScope: a New OCaml API SearchOCamlOScope: a New OCaml API Search
OCamlOScope: a New OCaml API SearchJun Furuse
 
W3C HTML5 KIG-How to write low garbage real-time javascript
W3C HTML5 KIG-How to write low garbage real-time javascriptW3C HTML5 KIG-How to write low garbage real-time javascript
W3C HTML5 KIG-How to write low garbage real-time javascriptChanghwan Yi
 
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCECONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCEVenugopalavarma Raja
 
Introduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoIntroduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoMuhammad Abdullah
 

Similar to Refactoring to Immutability (20)

Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functions
 
Lezione03
Lezione03Lezione03
Lezione03
 
Lezione03
Lezione03Lezione03
Lezione03
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 
Thread
ThreadThread
Thread
 
Lecture 5
Lecture 5Lecture 5
Lecture 5
 
05. Java Loops Methods and Classes
05. Java Loops Methods and Classes05. Java Loops Methods and Classes
05. Java Loops Methods and Classes
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief intro
 
Introduction to functional programming using Ocaml
Introduction to functional programming using OcamlIntroduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
 
Functional Scala 2020
Functional Scala 2020Functional Scala 2020
Functional Scala 2020
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
OCamlOScope: a New OCaml API Search
OCamlOScope: a New OCaml API SearchOCamlOScope: a New OCaml API Search
OCamlOScope: a New OCaml API Search
 
W3C HTML5 KIG-How to write low garbage real-time javascript
W3C HTML5 KIG-How to write low garbage real-time javascriptW3C HTML5 KIG-How to write low garbage real-time javascript
W3C HTML5 KIG-How to write low garbage real-time javascript
 
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCECONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
 
Introduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoIntroduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demo
 

More from Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test CasesKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our WaysKevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 

Recently uploaded

WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%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
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 

Recently uploaded (20)

WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%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
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 

Refactoring to Immutability

  • 2.
  • 4. Functional programming typically avoids using mutable state. https://wiki.haskell.org/Functional_programming
  • 5. https://xkcd.com/1270/ Functional programming combines the flexibility and power of abstract mathematics with the intuitive clarity of abstract mathematics.
  • 6. Rien n'est plus dangereux qu'une idée, quand on n'a qu'une idée. Émile-Auguste Chartier
  • 7. Nothing is more dangerous than an idea, when you have only one idea. Émile-Auguste Chartier
  • 9.
  • 10. Asking a question should not change the answer.
  • 11. To keep our C++ API boundary simple, we [...] adopted one-way data flow. The API consists of methods to perform fire-and-forget mutations and methods to compute view models required by specific views. To keep the code understandable, we write functional style code converting raw data objects into immutable view models by default. As we identified performance bottlenecks through profiling, we added caches to avoid recomputing unchanged intermediate results. The resulting functional code is easy to maintain, without sacrificing performance. https://code.facebook.com/posts/498597036962415/under-the-hood-building-moments/
  • 12.
  • 13.
  • 14.
  • 15. Excel is the world's most popular functional language Simon Peyton-Jones
  • 16. I want code to be reasonable
  • 17. As a programmer I want code to be reasonable
  • 22. As a programmer I want code to be reasonable so that I can reason about it
  • 23. A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 24. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation
  • 25. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation The Synchronisation Quadrant
  • 26.
  • 27. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change. Grady Booch
  • 28.
  • 30. There is a beautiful angel in that block of marble, and I am going to find it. All I have to do is to knock off the outside pieces of marble, and be very careful not to cut into the angel with my chisel. George F Pentecost "The Angel in the Marble"
  • 31.
  • 32.
  • 35.
  • 36. Nothing is more dangerous than an idea, when you have only one idea. Émile-Auguste Chartier
  • 37. Nothing is more dangerous than OO, when you have only one object.
  • 38.
  • 39. public class Clock { public static Clock Instance => ... public TimeOfDay Now => ... ... }
  • 40. public void Example() { var now = Clock.Instance.Now; ... }
  • 41. public void Example(Clock clock) { var now = clock.Now; ... }
  • 42. public interface Clock { TimeOfDay Now => ... } public class ClockImpl : Clock { public static Clock Instance => ... ... }
  • 43. public interface IClock { TimeOfDay Now => ... } public class Clock : IClock { public static IClock Instance => ... ... }
  • 44. public interface IClock { TimeOfDay Now => ... } public class LocalClock : IClock { public static IClock Instance => ... ... }
  • 45. public interface Clock { TimeOfDay Now => ... } public class LocalClock : Clock { public static Clock Instance => ... ... }
  • 46. public void Example(Func<TimeOfDay> timeOfDay) { var now = timeOfDay(); ... }
  • 48. public class TimeOfDay { ... public int Hour { get ... set ... } public int Minute { get ... set ... } public void NextHour() ... public void NextMinute() ... }
  • 49. public class TimeOfDay { private int minutes; public const int minutesInHour = 60; public const int hoursInDay = 24; public const int minutesInDay = hoursInDay * minutesInHour; private static int Wrap(int minutes) { return minutes % minutesInDay; } public int Hour { get { return minutes / minutesInHour; } set { if (value < 0 || value >= hoursInDay) throw new ArgumentException(); minutes = Wrap(value * minutesInHour + Minute); } } public int Minute { get { return minutes % minutesInHour; } set { if (value < 0 || value >= minutesInHour) throw new ArgumentException(); minutes = Wrap(Hour * minutesInHour + value); } } public void NextHour() { minutes = Wrap(minutes + minutesInHour); } public void NextMinute() { minutes = Wrap(minutes + 1); } }
  • 50. public class TimeOfDay { ... public int Hour { get ... set ... } public int Minute { get ... set ... } public void NextHour() ... public void NextMinute() ... }
  • 51. public class TimeOfDay { ... public int Hour { get ... set ... } public int Minute { get ... set ... } }
  • 52. public class TimeOfDay { ... public int Hour { get ... } public int Minute { get ... } }
  • 53. public class TimeOfDay { ... public int Hour => ... public int Minute => ... }
  • 54. public class TimeOfDay { ... public TimeOfDay(int hour, int minute) ... public int Hour => ... public int Minute => ... }
  • 55. public class TimeOfDay { ... public TimeOfDay(int hour, int minute) ... public int Hour => ... public int Minute => ... public TimeOfDay WithHour(int newHour) ... public TimeOfDay WithMinute(int newMinute) ... }
  • 56. public class TimeOfDay { ... public TimeOfDay(int hour, int minute) ... public int Hour => ... public int Minute => ... public TimeOfDay WithHour(int newHour) ... public TimeOfDay WithMinute(int newMinute) ... public TimeOfDay NextHour() ... public TimeOfDay NextMinute() ... }
  • 57. public class TimeOfDay { ... public TimeOfDay(int hour, int minute) ... public int Hour => ... public int Minute => ... public TimeOfDay WithHour(int newHour) ... public TimeOfDay WithMinute(int newMinute) ... public TimeOfDay NextHour() ... public TimeOfDay NextMinute() ... public class Builder { ... } }
  • 58. public class TimeOfDay { private readonly int minutes; public const int minutesInHour = 60; public const int hoursInDay = 24; public const int minutesInDay = hoursInDay * minutesInHour; private TimeOfDay(int minutes) { this.minutes = minutes % minutesInDay; } public TimeOfDay(int hour, int minute) { if (hour < 0 || hour >= hoursInDay || minute < 0 || minute >= minutesInHour) throw new ArgumentException(); minutes = hour * minutesInHour + minute; } public int Hour => minutes / minutesInHour; public int Minute => minutes % minutesInHour; public TimeOfDay WithHour(int newHour) => new TimeOfDay(newHour, Minute); public TimeOfDay WithMinute(int newMinute) => new TimeOfDay(Hour, newMinute); public TimeOfDay NextHour() => new TimeOfDay(minutes + minutesInHour); public TimeOfDay NextMinute() => new TimeOfDay(minutes + 1); ... }
  • 59.
  • 60. try { Integer.parseInt(time.substring(0, 2)); } catch (Exception x) { return false; } if (Integer.parseInt(time.substring(0, 2)) > 12) { return false; } ... if (!time.substring(9, 11).equals("AM") & !time.substring(9, 11).equals("PM")) { return false; } Burk Hufnagel "Put the Mouse Down and Step Away from the Keyboard"
  • 61. Burk Hufnagel "Put the Mouse Down and Step Away from the Keyboard" return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)");
  • 62. Je n'ai fait celle-ci plus longue que parce que je n'ai pas eu le loisir de la faire plus courte. Blaise Pascal
  • 63. I have made this [letter] longer than usual because I have not had time to make it shorter. Blaise Pascal
  • 64.
  • 65.
  • 66. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older? library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .limit(15) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .collect(toList())
  • 67. // Get the first 15 unique surnames in // uppercase of the book authors that are 50 // years old or older. library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .limit(15) .collect(toList())
  • 68. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older. library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .distinct() .limit(15) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .collect(toList())
  • 69. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older. library.stream() .map(book -> book.getAuthor()) .distinct() .filter(author -> author.getAge() >= 50) .limit(15) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .collect(toList())
  • 70.
  • 71. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older? List<Author> authors = new ArrayList<Author>(); for (Book book : library) { Author author = book.getAuthor(); if (author.getAge() >= 50) { authors.add(author); if (authors.size() == 15) break; }
  • 72. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older? List<Author> authors = new ArrayList<Author>(); for (Book book : library) { Author author = book.getAuthor(); if (author.getAge() >= 50) { authors.add(author); if (authors.size() == 15) break; } } List<String> result = new ArrayList<String>(); for(Author author : authors) { String name = author.getSurname().toUpperCase(); if (!result.contains(name)) result.add(name); }
  • 73. // Get the first 15 unique surnames in // uppercase of the book authors that are 50 // years old or older. List<String> result = new ArrayList<String>(); for (Book book : library) { Author author = book.getAuthor(); if (author.getAge() >= 50) { String name = author.getSurname().toUpperCase(); if (!result.contains(name)) { result.add(name); if (result.size() == 15) break; } } }
  • 74. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older. List<Author> authors = new ArrayList<Author>(); for (Book book : library) { Author author = book.getAuthor(); if (author.getAge() >= 50 && !authors.contains(author)) { authors.add(author); if (authors.size() == 15) break; } } List<String> result = new ArrayList<String>(); for(Author author : authors) { String name = author.getSurname().toUpperCase(); if (!result.contains(name)) result.add(name); }
  • 75. Try to leave out the part that readers tend to skip. Elmore Leonard
  • 76. When it is not necessary to change, it is necessary not to change. Lucius Cary