SlideShare a Scribd company logo
1 of 55
Shipping
Pseudocode to
Production
Dobromir Nikolov
What’s this about
RowData ParseRow(ExcelRow row);
ExcelRow[] rows = ReadExcelRows();
RowData[] parsedData = rows
.Select(ParseRow)
.ToArray();
try
{
ExcelRow[] rows = ReadExcelRows();
RowData[] parsedData = rows
.Select(ParseRow)
.ToArray();
}
catch (ParsingException e)
{
// Handle
}
An error report
class RowData
{
...
string Error { get; set; }
...
}
class ParsingResult
{
RowData Data { get; set; }
string Error { get; set; }
}
ExcelRow row = ReadExcelRow();
ParsingResult result = ParseRow(row);
if (result.Error == null)
{
// Do something with result.Data
}
else
{
// Handle the error
}
Why?
Expressiveness
Expressiveness through types
Our first expressive function
The case - model a function that performs an HTTP
request
Details
- HTTP has 62 status codes but only 10 of them mean success
- The chance of receiving an error is 84%
therefore
- The caller should be signaled unambiguously that errors are likely to
occur
- It should be easy for the caller to handle the potential errors
How?
Communicating through the return type
Designing our type
Requirements
1. It should be able to contain 2 other types - one that is going to be
returned if the operation went successfully and another one if it failed
a. In the HTTP request case, we would like one type of response if the server returned a
status code of 2XX and another one if it failed
2. It should never be null
a. It makes no sense for a type that signals a likely error to be null as that will lead to even
more errors
public struct Either<T, TException>
{
...
public bool HasValue { get; }
...
public static Either<T, TException> Success(T value) =>
new Either<T, TException>(value);
public static Either<T, TException> Error(TException exception) =>
new Either<T, TException>(exception);
}
Either<SucessfulHttpResponse, HttpError> PerformHttpRequest(...)
Either<SucessfulHttpResponse, HttpError> responseResult =
PerformHttpRequest("GET", "http://someurl.com/");
// ??????
public struct Either<T, TException>
{
// Implementation details omitted for brevity
public bool HasValue { get; private set; }
public void Match(Action<T> some, Action<TException> none) =>
HasValue ? some(value) : none(exception);
public TResult Match<TResult>(Func<T, TResult> some, Func<TException, TResult> none) =>
HasValue ? some(value) : none(exception);
}
Either<SucessfulHttpResponse, HttpError> responseResult =
PerformHttpRequest("GET", "http://someurl.com/");
// Compiler error
responseResult.Match(
some: response => ...
)
Either<SucessfulHttpResponse, HttpError> responseResult =
PerformHttpRequest("GET", "http://someurl.com/");
responseResult.Match(
some: response => /* Happy path */,
none: error => /* Sad path */
)
Performing consecutive requests
HttpResponse response = HttpRequest(...);
if (response.IsSuccessfull)
{
HttpResponse anotherResponse = HttpRequest(... response.Data);
if (anotherResponse.IsSuccessfull)
{
HttpResponse thirdResponse = HttpRequest(... anotherResponse.Data);
if (thirdResponse.IsSuccessfull)
{
}
}
}
var responseResult = HttpRequest(...);
responseResult.Match(
some: response =>
{
var anotherResponseResult = HttpRequest(... response.Data);
anotherResponseResult.Match(
some: anotherResponse =>
{
var thirdResponseResult = HttpRequest(... anotherResponse.Data);
thirdResponseResult.Match(
some: thirdResponse
{
},
error: /* Error handling */
)
},
error: /* Error handling */
)
},
error: /* Error handling */
)
// Perform a request
// If the request is successful, perform another request
// If the consequent request is successful, perform another request
// ...
// Perform a request
// If the request is successful, perform another request
// If the consequent request is successful, perform another request
// If the consequent request is successful, perform another request
// Perform a request
// If the request operation is successful, perform another request operation
// If the consequent request operation is successful, perform another request
operation
// If the consequent request operation is successful, perform another request
operation
public struct Either<T, TException>
{
public Either<TResult, TException> Map<TResult>(Func<T, TResult> mapping) =>
Match(
some: value => Either.Success<TResult, TException>(mapping(value)),
none: exception => Either.Error<TResult, TException>(exception)
);
}
var responseResult = HttpRequest(...);
responseResult.Map(response =>
{
var anotherResponseResult = HttpRequest(... response.Data);
anotherResponseResult.Map(anotherResponse =>
{
var thirdResponseResult = HttpRequest(... anotherResponse.Data);
thirdResponseResult.Map(thirdResponse =>
{
})
})
})
HttpRequest(...).Map(response =>
HttpRequest(... response.Data).Map(anotherResponse =>
HttpRequest(... anotherResponse.Data).Map(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
Either<SuccessfulHttpResponse, HttpError> ChainFour() =>
HttpRequest(...).Map(response =>
HttpRequest(... response.Data).Map(anotherResponse =>
HttpRequest(... anotherResponse.Data).Map(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
The type of
HttpRequest(...).Map(response =>
HttpRequest(... response.Data).Map(anotherResponse =>
HttpRequest(... anotherResponse.Data).Map(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
is
Either<Either<Either<Either<Sucessful
HttpResponse, HttpError>, HttpError>,
HttpError>, HttpError>
Either<Either<Either<Either<SucessfulHttpResponse, HttpError>, HttpError>,
HttpError>, HttpError>
->
Either<SucessfulHttpResponse, HttpError>
HttpRequest(...).Map(response =>
HttpRequest(... response.Data).Map(anotherResponse =>
HttpRequest(... anotherResponse.Data).Map(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
Either<SuccessfulHttpResponse, HttpError>
->
Map the SuccessfulHttpResponse into Either<SuccessfulHttpResponse, HttpError>
->
Either<Either<SuccessfulHttpResponse, HttpError>, HttpError>
public struct Either<T, TException>
{
public Either<TResult, TException> Map<TResult>(Func<T, TResult> mapping) =>
Match(
some: value => Either.Success<TResult, TException>(mapping(value)),
none: exception => Either.Error<TResult, TException>(exception)
);
}
public struct Either<T, TException>
{
public Either<TResult, TException> FlatMap<TResult>(Func<T, Either<TResult, TException>> mapping) =>
Match(
some: mapping, // We skip wrapping the value into an Either
none: exception => Either.Error<TResult, TException>(exception)
);
}
HttpRequest(...).FlatMap(response =>
HttpRequest(... response.Data).FlatMap(anotherResponse =>
HttpRequest(... anotherResponse.Data).FlatMap(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
Either<SuccessfulHttpResponse, HttpError> ChainFour() =>
HttpRequest(...).FlatMap(response =>
HttpRequest(... response.Data).FlatMap(anotherResponse =>
HttpRequest(... anotherResponse.Data).FlatMap(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
HttpResponse response = HttpRequest(...);
if (response.IsSuccessfull)
{
HttpResponse anotherResponse = HttpRequest(... response.Data);
if (anotherResponse.IsSuccessfull)
{
HttpResponse thirdResponse = HttpRequest(... anotherResponse.Data);
if (thirdResponse.IsSuccessfull)
{
HttpResponse fourthResponse = HttpRequest(... thirdResponse.Data);
if (fourthResponse.IsSuccessfull)
{
}
}
}
}
HttpRequest(...).FlatMap(response =>
HttpRequest(... response.Data).FlatMap(anotherResponse =>
HttpRequest(... anotherResponse.Data).FlatMap(thirdResponse =>
HttpRequest(... thirdResponse.Data))))
Going into production
1
4
3
5
2
// function ProcessDocument userId, category, file
// 1. check if the user is authorized
// 2. store the file into the cloud
// 3. store database log with unique key
// 4. send the unique key to an external service for post-processing
Either<User, Error> CheckIfUserIsAuthorized(string userId, string category);
Either<CloudRecord, Error> StoreTheFileIntoTheCloud(File file, string category);
Either<Guid, Error> StoreDatabaseLog(CloudRecord record);
Either<DocumentProcessedResult, Error> SendToExternalService(Guid key);
Either<DocumentProcessedResult, Error> ProcessDocument(
string userId,
string category,
File file) =>
CheckIfUserIsAuthorized(userId, category).FlatMap(user =>
StoreTheFileIntoTheCloud(file, category).FlatMap(cloudRecord =>
StoreDatabaseLog(cloudRecord).FlatMap(uniqueKey =>
SendToExternalService(uniqueKey))));
Where next?
● Dev Adventures .NET Core template (link)
● A real world API using Either (link)
● A CLI tool for managing your music collection (link)
● A sample application using DDD and event-sourcing with complete
integration tests coverage (link)
● Real life examples of Either in C# (link)
Q&A
Thanks!

More Related Content

What's hot

Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesGanesh Samarthyam
 
Important java programs(collection+file)
Important java programs(collection+file)Important java programs(collection+file)
Important java programs(collection+file)Alok Kumar
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidJordi Gerona
 
JavaScript Arrays
JavaScript Arrays JavaScript Arrays
JavaScript Arrays Reem Alattas
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheeltcurdt
 
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistRiga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistAnton Arhipov
 
The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.10 book - Part 17 of 212The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.10 book - Part 17 of 212Mahmoud Samir Fayed
 
JDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJosé Paumard
 
Google Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG NantesGoogle Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG Nantesmikaelbarbero
 

What's hot (20)

Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Important java programs(collection+file)
Important java programs(collection+file)Important java programs(collection+file)
Important java programs(collection+file)
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Java programs
Java programsJava programs
Java programs
 
JavaScript Arrays
JavaScript Arrays JavaScript Arrays
JavaScript Arrays
 
What are arrays in java script
What are arrays in java scriptWhat are arrays in java script
What are arrays in java script
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
 
srgoc
srgocsrgoc
srgoc
 
Java Generics - by Example
Java Generics - by ExampleJava Generics - by Example
Java Generics - by Example
 
Java Annotations and Pre-processing
Java  Annotations and Pre-processingJava  Annotations and Pre-processing
Java Annotations and Pre-processing
 
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistRiga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
 
The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.10 book - Part 17 of 212The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.10 book - Part 17 of 212
 
JDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easy
 
Google Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG NantesGoogle Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG Nantes
 

Similar to Shipping Pseudocode to Production with Either

Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Datagreenwop
 
JS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js AntipatternsJS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js AntipatternsTimur Shemsedinov
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8Sergiu Mircea Indrie
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016Frank Lyaruu
 
Unit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterUnit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterWayan Wira
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Concurrency on the JVM
Concurrency on the JVMConcurrency on the JVM
Concurrency on the JVMVaclav Pech
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
Переход на Scala: босиком по граблям
Переход на Scala: босиком по граблямПереход на Scala: босиком по граблям
Переход на Scala: босиком по граблямSveta Bozhko
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeletonIram Ramrajkar
 

Similar to Shipping Pseudocode to Production with Either (20)

Rx workshop
Rx workshopRx workshop
Rx workshop
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
JS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js AntipatternsJS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js Antipatterns
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8
 
Akka tips
Akka tipsAkka tips
Akka tips
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
What is new in Java 8
What is new in Java 8What is new in Java 8
What is new in Java 8
 
Unit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterUnit testing CourseSites Apache Filter
Unit testing CourseSites Apache Filter
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
In kor we Trust
In kor we TrustIn kor we Trust
In kor we Trust
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Servlets intro
Servlets introServlets intro
Servlets intro
 
Concurrency on the JVM
Concurrency on the JVMConcurrency on the JVM
Concurrency on the JVM
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Переход на Scala: босиком по граблям
Переход на Scala: босиком по граблямПереход на Scala: босиком по граблям
Переход на Scala: босиком по граблям
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 

Recently uploaded

Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsAndrey Dotsenko
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 

Recently uploaded (20)

Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 

Shipping Pseudocode to Production with Either

Editor's Notes

  1. Ask what’s wrong. You don’t know if this returns null or throws an exception if it can’t parse. No way to aggregate errors. (You can put an “Errors” property in the RowData class but is basically fucking with the single responsibility principle)
  2. Let’s say it throws an exception
  3. Represents row data but has an Error property?
  4. Ask why did this situation occur...
  5. The answer is because the library you were using lacks expressiveness.
  6. Most of you write in compiled languages, and using types allows you to leverage the compiler as much as possible.
  7. This results in compiler error
  8. How are we going to transform this, and aren’t we going to lose information?
  9. We’re only going to have one error or one result. The nesting is meaningless.
  10. We’re only going to have one error or one result. The nesting is meaningless.
  11. This now works.
  12. To this
  13. A user uploads a file with a category. The server checks if the user has rights for this category. The server stores the file into some cloud storage (AWS S3 for example). The server takes the cloud storage id and stores it into a database with a newly generated unique key. The unique key is then sent to an external service.
  14. Each function is looked upon as a separate operation, and the process function is going to be simply a composition of these operations. It’s much easier to avoid bugs and structure your thinking when you have clearly defined “goals” of what an operation should do.
  15. Note on integration testing: it’s very easy to reason about this thing as having at least one test per line.