SlideShare una empresa de Scribd logo
1 de 76
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

Introduction to JavaScript (1).ppt
Introduction to JavaScript (1).pptIntroduction to JavaScript (1).ppt
Introduction to JavaScript (1).pptMuhammadRehan856177
 
گنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdf
گنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdfگنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdf
گنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdfFaizan ali Siddiqui
 
Html heading
Html headingHtml heading
Html headingsaichii27
 
IGCSE & O Level Computer Workbook for P2 by Inqilab Patel
IGCSE & O Level Computer Workbook for P2 by Inqilab PatelIGCSE & O Level Computer Workbook for P2 by Inqilab Patel
IGCSE & O Level Computer Workbook for P2 by Inqilab PatelInqilab Patel
 

La actualidad más candente (15)

Algorand
AlgorandAlgorand
Algorand
 
Blockchain
BlockchainBlockchain
Blockchain
 
Brain to Brain Interface
Brain to Brain Interface Brain to Brain Interface
Brain to Brain Interface
 
Html
HtmlHtml
Html
 
BLOCK CHAIN
BLOCK CHAINBLOCK CHAIN
BLOCK CHAIN
 
Brain gate technology(AI)
Brain gate technology(AI)Brain gate technology(AI)
Brain gate technology(AI)
 
Fpadscrλnd
FpadscrλndFpadscrλnd
Fpadscrλnd
 
Dapps ppt
Dapps pptDapps ppt
Dapps ppt
 
Vb script
Vb scriptVb script
Vb script
 
Introduction to JavaScript (1).ppt
Introduction to JavaScript (1).pptIntroduction to JavaScript (1).ppt
Introduction to JavaScript (1).ppt
 
Html example
Html exampleHtml example
Html example
 
Bootstrap grids
Bootstrap gridsBootstrap grids
Bootstrap grids
 
گنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdf
گنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdfگنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdf
گنجینہ اسرار (محمد انور شاہ کشمیری مرقداللہ نورہ).pdf
 
Html heading
Html headingHtml heading
Html heading
 
IGCSE & O Level Computer Workbook for P2 by Inqilab Patel
IGCSE & O Level Computer Workbook for P2 by Inqilab PatelIGCSE & O Level Computer Workbook for P2 by Inqilab Patel
IGCSE & O Level Computer Workbook for P2 by Inqilab Patel
 

Similar a 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 a 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
 

Más de 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
 

Más de 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
 

Último

Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 

Último (20)

Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 

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