SlideShare a Scribd company logo
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

PDF
Google guava
PDF
5. Ввод-вывод, доступ к файловой системе
ODP
Java Generics
PDF
JEEConf 2017 - Having fun with Javassist
PDF
Google Guava for cleaner code
PDF
Google guava - almost everything you need to know
PDF
The core libraries you always wanted - Google Guava
PDF
3. Объекты, классы и пакеты в Java
Google guava
5. Ввод-вывод, доступ к файловой системе
Java Generics
JEEConf 2017 - Having fun with Javassist
Google Guava for cleaner code
Google guava - almost everything you need to know
The core libraries you always wanted - Google Guava
3. Объекты, классы и пакеты в Java

What's hot (20)

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

Similar to Shipping Pseudocode to Production VarnaLab (20)

PPTX
Rx workshop
PPTX
Category theory, Monads, and Duality in the world of (BIG) Data
PDF
JS Fest 2019 Node.js Antipatterns
PDF
Writing beautiful code with Java 8
PDF
PPTX
The Road To Reactive with RxJava JEEConf 2016
PPTX
Nantes Jug - Java 7
PDF
Clean coding-practices
PDF
Solr @ Etsy - Apache Lucene Eurocon
PPTX
What is new in Java 8
PPTX
Unit testing CourseSites Apache Filter
PDF
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
PPTX
Anti patterns
PPTX
In kor we Trust
PDF
Reactive programming on Android
PDF
JavaScript Array Interview Questions PDF By ScholarHat
PDF
Servlets intro
ODP
Concurrency on the JVM
PPTX
Is your C# optimized
PDF
Переход на Scala: босиком по граблям
Rx workshop
Category theory, Monads, and Duality in the world of (BIG) Data
JS Fest 2019 Node.js Antipatterns
Writing beautiful code with Java 8
The Road To Reactive with RxJava JEEConf 2016
Nantes Jug - Java 7
Clean coding-practices
Solr @ Etsy - Apache Lucene Eurocon
What is new in Java 8
Unit testing CourseSites Apache Filter
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Anti patterns
In kor we Trust
Reactive programming on Android
JavaScript Array Interview Questions PDF By ScholarHat
Servlets intro
Concurrency on the JVM
Is your C# optimized
Переход на Scala: босиком по граблям
Ad

Recently uploaded (20)

PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Empathic Computing: Creating Shared Understanding
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Encapsulation theory and applications.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Electronic commerce courselecture one. Pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Getting Started with Data Integration: FME Form 101
“AI and Expert System Decision Support & Business Intelligence Systems”
MIND Revenue Release Quarter 2 2025 Press Release
Advanced methodologies resolving dimensionality complications for autism neur...
Empathic Computing: Creating Shared Understanding
20250228 LYD VKU AI Blended-Learning.pptx
A comparative analysis of optical character recognition models for extracting...
Encapsulation theory and applications.pdf
Encapsulation_ Review paper, used for researhc scholars
Programs and apps: productivity, graphics, security and other tools
Unlocking AI with Model Context Protocol (MCP)
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Electronic commerce courselecture one. Pdf
Machine learning based COVID-19 study performance prediction
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Getting Started with Data Integration: FME Form 101

Shipping Pseudocode to Production VarnaLab

Editor's Notes

  • #4: 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)
  • #5: Let’s say it throws an exception
  • #8: Represents row data but has an Error property?
  • #11: Ask why did this situation occur...
  • #12: The answer is because the library you were using lacks expressiveness.
  • #13: Most of you write in compiled languages, and using types allows you to leverage the compiler as much as possible.
  • #36: This results in compiler error
  • #39: How are we going to transform this, and aren’t we going to lose information?
  • #40: We’re only going to have one error or one result. The nesting is meaningless.
  • #44: We’re only going to have one error or one result. The nesting is meaningless.
  • #45: This now works.
  • #47: To this
  • #49: 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.
  • #51: 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.
  • #52: Note on integration testing: it’s very easy to reason about this thing as having at least one test per line.