SlideShare a Scribd company logo
1 of 35
Download to read offline
FUNCTIONAL PROGRAMMING IN SCALA
(from error handling to fp)
TEXT
About me…
▸ Jordi Pradel
▸ Agile software developer
▸ Learning functional programming
▸ @agile_jordi
FP IS JUST PROGRAMMING WITH FUNCTIONS. FUNCTIONS ARE:
1. TOTAL: THEY RETURN AN OUTPUT FOR EVERY INPUT.
2. DETERMINISTIC: THEY RETURN THE SAME OUTPUT FOR THE SAME
INPUT.
3. PURE: THEIR ONLY EFFECT IS COMPUTING THE OUTPUT.
THE REST IS JUST COMPOSITION YOU CAN LEARN OVER TIME.
John De Goes
TEXT
ABSTRACT OVER COMPOSITION
;
; aka andThen aka flatMap
▸ Whats the meaning of this program?
expressionA; expressionB
https://github.com/agile-jordi/error-handling-to-fp
SHOW ME THE CODE!
IMPERATIVE
class DocumentService(documentRepository: DocumentRepository) {
def saveDocumentIfNotFound(document: Document): Unit = {
val documentExists =
documentRepository.getDocument(document.id).nonEmpty
if (documentExists) {
documentRepository.updateDocument(document)
} else {
documentRepository.insertDocument(document)
}
}
}
FUNCTIONAL
class DocumentService[F[_] : Monad : DocumentRepository] {
private val documentRepository = implicitly[DocumentRepository[F]]
def saveDocumentIfNotFound(document: Document): F[Unit] = {
for {
doc <- documentRepository.getDocument(document.id)
_ <- if (doc.nonEmpty) {
documentRepository.updateDocument(document)
} else {
documentRepository.insertDocument(document)
}
} yield ()
}
}
FUNCTIONAL
trait DocumentRepository[F[_]] {
def getDocument(documentId: DocumentId): F[Option[Document]]
def insertDocument(document: Document): F[Unit]
def updateDocument(document: Document): F[Unit]
}
TRANSACTIONS!
IMPERATIVE
class DocumentService(
documentRepository: DocumentRepository,
transactionController: TransactionController) {
def saveDocumentIfNotFound(document: Document): Unit = {
transactionController.inTransaction {
conn =>
val documentExists =
documentRepository.getDocument(document.id)(conn).nonEmpty
if (documentExists) {
documentRepository.updateDocument(document)(conn)
} else {
documentRepository.insertDocument(document)(conn)
}
}
}
}
IMPERATIVE
class TransactionController(dataSource: DataSource) {
def inTransaction[T](f: Connection => T): T = {
val conn = dataSource.getConnection()
try {
conn.beginTransaction()
val res = f(conn)
conn.commit()
res
} catch {
case NonFatal(t) =>
//TODO: Proper error handling of rollback
conn.rollback()
throw t
}
}
}
FUNCTIONAL
class DocumentService(
documentRepository: DocumentRepository,
transactionController: TransactionController) {
def saveDocumentIfNotFound(document: Document): F[Unit] = {
transactionController.inTransaction {
for {
doc <- documentRepository.getDocument(document.id)
_ <- if (doc.nonEmpty) {
documentRepository.updateDocument(document)
} else {
documentRepository.insertDocument(document)
}
} yield ()
}
}
}
FUNCTIONAL
trait DocumentRepository {
def getDocument(documentId: DocumentId): TxAction[Option[Document]]
def insertDocument(document: Document): TxAction[Unit]
def updateDocument(document: Document): TxAction[Unit]
}
FUNCTIONAL
trait TransactionController {
def begin(): F[Transaction]
def commit(tx: Transaction): F[Unit]
def rollback(tx: Transaction): F[Unit]
def inTransaction[T](f: TxAction[T]): F[T] = {
for {
tx <- begin()
res <- f.run(tx)
_ <- commit(tx)
} yield res
}
}
FUNCTIONAL
trait Documents[F[_]] {
implicit def M:Monad[F]
type Transaction
type TxAction[A] = Kleisli[F, Transaction, A]
// ~= Transaction => F[A]
object TxAction{
def apply[A](f: Transaction => F[A]): TxAction[A] = Kleisli(f)
}
class DocumentService(…) {…}
trait TransactionController {…}
trait DocumentRepository {…}
}
ERROR HANDLING!!!
IMPERATIVE
class DocumentService(
documentRepository: DocumentRepository,
transactionController: TransactionController) {
def saveDocumentIfNotFound(document: Document):
Either[ConnectionError, Unit] = {
transactionController.inTransaction {
for {
doc <- documentRepository.getDocument(document.id)
_ <- if (doc.nonEmpty) {
documentRepository.updateDocument(document)
} else {
documentRepository.insertDocument(document)
}
} yield ()
}
}
}
IMPERATIVE
trait DocumentRepository {
def getDocument(documentId: DocumentId)(conn: Connection):
Either[ConnectionError, Option[Document]]
def insertDocument(document: Document)(conn: Connection):
Either[InsertDocumentError, Unit]
def updateDocument(document: Document)(conn: Connection):
Either[UpdateDocumentError, Unit]
}
FUNCTIONAL
▸ I was preparing a blog post or a talk about pure functional
error handling
▸ It was about typeclasses like ApplicativeError,
MonadError… (similar to how Future handles errors)
▸ I may still talk about them
▸ But suddenly….
ABOUT MONADERROR…
FUNCTIONAL
▸ So I’ll simplify and use F[Either[E,A]] for any F Monad you
choose
type Action[E, A] = F[Either[E, A]
FUNCTIONAL
class DocumentService(
documentRepository: DocumentRepository,
transactionController: TransactionController) {
def saveDocumentIfNotFound(document: Document):
Action[ConnectionError, Unit] = {
transactionController.inTransaction {
for {
doc <- documentRepository.getDocument(document.id)
_ <- if (doc.nonEmpty) {
documentRepository.updateDocument(document)
} else {
documentRepository.insertDocument(document)
}
} yield ()
}
}
}
FUNCTIONAL
trait DocumentRepository {
def getDocument(documentId: DocumentId):
TxAction[ConnectionError, Option[Document]]
def insertDocument(document: Document):
TxAction[InsertDocumentError, Unit]
def updateDocument(document: Document):
TxAction[UpdateDocumentError, Unit]
}
FUNCTIONAL
trait Documents[F[_]] {
implicit def M: Monad[F]
type Transaction
type Action[E, A] = EitherT[F, E, A] // ~= F[Either[E,A]]
object Action {
def apply[E, A](s: F[Either[E, A]]): EitherT[F, E, A] = EitherT.fromEither(s)
}
type TxAction[E, A] = Kleisli[Action[E, ?], Transaction, A] // ~= Transaction => Action[E,A]
object TxAction {
def apply[E, A](f: Transaction => Action[E, A]): TxAction[E, A] =
Kleisli[Action[E, ?], Transaction, A](f)
}
implicit def txActionBifunctor: Bifunctor[TxAction] = new Bifunctor[TxAction] {
override def bimap[A, B, C, D](fab: TxAction[A, B])(f: A => C, g: B => D):
TxAction[C, D] =
TxAction { tx => fab.run(tx).bimap(f, g)}
}
…
}
BIFUNCTOR!
EITHERT AND MONADTRANSFORMERS
EITHERT AND MONADTRANSFORMERS
▸ https://github.com/scalaz/scalaz/pull/1708
EITHERT AND MONADTRANSFORMERS
FUNCTIONAL
class DocumentService(
documentRepository: DocumentRepository,
transactionController: TransactionController) {
def saveDocumentIfNotFound(document: Document):
F[ConnectionError, Unit] = {
transactionController.inTransaction {
for {
doc <- documentRepository.getDocument(document.id)
_ <- if (doc.nonEmpty) {
documentRepository.updateDocument(document)
} else {
documentRepository.insertDocument(document)
}
} yield ()
}
}
}
FUNCTIONAL
trait DocumentRepository {
def getDocument(documentId: DocumentId):
TxAction[ConnectionError, Option[Document]]
def insertDocument(document: Document):
TxAction[InsertDocumentError, Unit]
def updateDocument(document: Document):
TxAction[UpdateDocumentError, Unit]
}
FUNCTIONAL
trait Documents[F[+ _, + _]] extends Transactional[F] {
implicit def M[E]: Monad[F[E, ?]]
class DocumentService(…) {…}
trait TransactionController {…}
trait DocumentRepository {…}
}
FUNCTIONAL
trait Transactional[F[+_,+_]]{
implicit def B:Bitraverse[F]
type Transaction
type TxAction[E, A] = Kleisli[F[E, ?], Transaction, A]
// ~== Transaction => F[E,A]
object TxAction {
def apply[E, A](f: Transaction => F[E, A]): TxAction[E, A] =
Kleisli[F[E, ?], Transaction, A](f)
}
protected implicit val BT: Bifunctor[TxAction] =
KleisiUtils.kleisliBifunctor[F,Transaction]
}
OUCH! SERIOUSLY??

More Related Content

What's hot

COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILECOMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILEAnushka Rai
 
function in c
function in cfunction in c
function in csubam3
 
LINQ Internals - STLDODN
LINQ Internals - STLDODNLINQ Internals - STLDODN
LINQ Internals - STLDODNKeith Dahlby
 
Labsheet 7 FP 201
Labsheet 7 FP 201Labsheet 7 FP 201
Labsheet 7 FP 201rohassanie
 
Learn c++ (functions) with nauman ur rehman
Learn  c++ (functions) with nauman ur rehmanLearn  c++ (functions) with nauman ur rehman
Learn c++ (functions) with nauman ur rehmanNauman Rehman
 
FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3rohassanie
 
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...tdc-globalcode
 
Call by value or call by reference in C++
Call by value or call by reference in C++Call by value or call by reference in C++
Call by value or call by reference in C++Sachin Yadav
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Juan Pablo
 

What's hot (19)

COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILECOMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
 
functions of C++
functions of C++functions of C++
functions of C++
 
Fp201 unit4
Fp201 unit4Fp201 unit4
Fp201 unit4
 
function in c
function in cfunction in c
function in c
 
LINQ Internals - STLDODN
LINQ Internals - STLDODNLINQ Internals - STLDODN
LINQ Internals - STLDODN
 
C++ programming function
C++ programming functionC++ programming function
C++ programming function
 
Labsheet 7 FP 201
Labsheet 7 FP 201Labsheet 7 FP 201
Labsheet 7 FP 201
 
Learn c++ (functions) with nauman ur rehman
Learn  c++ (functions) with nauman ur rehmanLearn  c++ (functions) with nauman ur rehman
Learn c++ (functions) with nauman ur rehman
 
FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3
 
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
 
CHAPTER 6
CHAPTER 6CHAPTER 6
CHAPTER 6
 
lets play with "c"..!!! :):)
lets play with "c"..!!! :):)lets play with "c"..!!! :):)
lets play with "c"..!!! :):)
 
Array notes
Array notesArray notes
Array notes
 
Introduction to Go for Java Programmers
Introduction to Go for Java ProgrammersIntroduction to Go for Java Programmers
Introduction to Go for Java Programmers
 
Call by value or call by reference in C++
Call by value or call by reference in C++Call by value or call by reference in C++
Call by value or call by reference in C++
 
DIG1108 Lesson 6
DIG1108 Lesson 6DIG1108 Lesson 6
DIG1108 Lesson 6
 
Functions
FunctionsFunctions
Functions
 
Programs of C++
Programs of C++Programs of C++
Programs of C++
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 

Similar to Functional programming in Scala: From error handling to fp

Improving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con BerlinImproving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con BerlinIain Hull
 
Functional GUIs with F#
Functional GUIs with F#Functional GUIs with F#
Functional GUIs with F#Frank Krueger
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingCodemotion
 
Improving Correctness with Types Kats Conf
Improving Correctness with Types Kats ConfImproving Correctness with Types Kats Conf
Improving Correctness with Types Kats ConfIain Hull
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8RichardWarburton
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional ProgrammingLuka Jacobowitz
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concernssaintiss
 
Pres_python_talakhoury_26_09_2023.pdf
Pres_python_talakhoury_26_09_2023.pdfPres_python_talakhoury_26_09_2023.pdf
Pres_python_talakhoury_26_09_2023.pdfRamziFeghali
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with TypesIain Hull
 
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Compiler Construction | Lecture 2 | Declarative Syntax DefinitionCompiler Construction | Lecture 2 | Declarative Syntax Definition
Compiler Construction | Lecture 2 | Declarative Syntax DefinitionEelco Visser
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 
SeneJug java_8_prez_122015
SeneJug java_8_prez_122015SeneJug java_8_prez_122015
SeneJug java_8_prez_122015senejug
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1saydin_soft
 

Similar to Functional programming in Scala: From error handling to fp (20)

Improving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con BerlinImproving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con Berlin
 
Functional GUIs with F#
Functional GUIs with F#Functional GUIs with F#
Functional GUIs with F#
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Improving Correctness with Types Kats Conf
Improving Correctness with Types Kats ConfImproving Correctness with Types Kats Conf
Improving Correctness with Types Kats Conf
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concerns
 
Pres_python_talakhoury_26_09_2023.pdf
Pres_python_talakhoury_26_09_2023.pdfPres_python_talakhoury_26_09_2023.pdf
Pres_python_talakhoury_26_09_2023.pdf
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with Types
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Friendly Functional Programming
Friendly Functional ProgrammingFriendly Functional Programming
Friendly Functional Programming
 
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Compiler Construction | Lecture 2 | Declarative Syntax DefinitionCompiler Construction | Lecture 2 | Declarative Syntax Definition
Compiler Construction | Lecture 2 | Declarative Syntax Definition
 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.ppt
 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.ppt
 
functions
functionsfunctions
functions
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
SeneJug java_8_prez_122015
SeneJug java_8_prez_122015SeneJug java_8_prez_122015
SeneJug java_8_prez_122015
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1
 

Recently uploaded

Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...masabamasaba
 
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburgmasabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
%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
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 

Recently uploaded (20)

Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
 
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
%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
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

Functional programming in Scala: From error handling to fp

  • 1. FUNCTIONAL PROGRAMMING IN SCALA (from error handling to fp)
  • 2. TEXT About me… ▸ Jordi Pradel ▸ Agile software developer ▸ Learning functional programming ▸ @agile_jordi
  • 3. FP IS JUST PROGRAMMING WITH FUNCTIONS. FUNCTIONS ARE: 1. TOTAL: THEY RETURN AN OUTPUT FOR EVERY INPUT. 2. DETERMINISTIC: THEY RETURN THE SAME OUTPUT FOR THE SAME INPUT. 3. PURE: THEIR ONLY EFFECT IS COMPUTING THE OUTPUT. THE REST IS JUST COMPOSITION YOU CAN LEARN OVER TIME. John De Goes TEXT
  • 5. ; aka andThen aka flatMap ▸ Whats the meaning of this program? expressionA; expressionB
  • 7. IMPERATIVE class DocumentService(documentRepository: DocumentRepository) { def saveDocumentIfNotFound(document: Document): Unit = { val documentExists = documentRepository.getDocument(document.id).nonEmpty if (documentExists) { documentRepository.updateDocument(document) } else { documentRepository.insertDocument(document) } } }
  • 8. FUNCTIONAL class DocumentService[F[_] : Monad : DocumentRepository] { private val documentRepository = implicitly[DocumentRepository[F]] def saveDocumentIfNotFound(document: Document): F[Unit] = { for { doc <- documentRepository.getDocument(document.id) _ <- if (doc.nonEmpty) { documentRepository.updateDocument(document) } else { documentRepository.insertDocument(document) } } yield () } }
  • 9. FUNCTIONAL trait DocumentRepository[F[_]] { def getDocument(documentId: DocumentId): F[Option[Document]] def insertDocument(document: Document): F[Unit] def updateDocument(document: Document): F[Unit] }
  • 11. IMPERATIVE class DocumentService( documentRepository: DocumentRepository, transactionController: TransactionController) { def saveDocumentIfNotFound(document: Document): Unit = { transactionController.inTransaction { conn => val documentExists = documentRepository.getDocument(document.id)(conn).nonEmpty if (documentExists) { documentRepository.updateDocument(document)(conn) } else { documentRepository.insertDocument(document)(conn) } } } }
  • 12. IMPERATIVE class TransactionController(dataSource: DataSource) { def inTransaction[T](f: Connection => T): T = { val conn = dataSource.getConnection() try { conn.beginTransaction() val res = f(conn) conn.commit() res } catch { case NonFatal(t) => //TODO: Proper error handling of rollback conn.rollback() throw t } } }
  • 13. FUNCTIONAL class DocumentService( documentRepository: DocumentRepository, transactionController: TransactionController) { def saveDocumentIfNotFound(document: Document): F[Unit] = { transactionController.inTransaction { for { doc <- documentRepository.getDocument(document.id) _ <- if (doc.nonEmpty) { documentRepository.updateDocument(document) } else { documentRepository.insertDocument(document) } } yield () } } }
  • 14. FUNCTIONAL trait DocumentRepository { def getDocument(documentId: DocumentId): TxAction[Option[Document]] def insertDocument(document: Document): TxAction[Unit] def updateDocument(document: Document): TxAction[Unit] }
  • 15. FUNCTIONAL trait TransactionController { def begin(): F[Transaction] def commit(tx: Transaction): F[Unit] def rollback(tx: Transaction): F[Unit] def inTransaction[T](f: TxAction[T]): F[T] = { for { tx <- begin() res <- f.run(tx) _ <- commit(tx) } yield res } }
  • 16. FUNCTIONAL trait Documents[F[_]] { implicit def M:Monad[F] type Transaction type TxAction[A] = Kleisli[F, Transaction, A] // ~= Transaction => F[A] object TxAction{ def apply[A](f: Transaction => F[A]): TxAction[A] = Kleisli(f) } class DocumentService(…) {…} trait TransactionController {…} trait DocumentRepository {…} }
  • 18. IMPERATIVE class DocumentService( documentRepository: DocumentRepository, transactionController: TransactionController) { def saveDocumentIfNotFound(document: Document): Either[ConnectionError, Unit] = { transactionController.inTransaction { for { doc <- documentRepository.getDocument(document.id) _ <- if (doc.nonEmpty) { documentRepository.updateDocument(document) } else { documentRepository.insertDocument(document) } } yield () } } }
  • 19. IMPERATIVE trait DocumentRepository { def getDocument(documentId: DocumentId)(conn: Connection): Either[ConnectionError, Option[Document]] def insertDocument(document: Document)(conn: Connection): Either[InsertDocumentError, Unit] def updateDocument(document: Document)(conn: Connection): Either[UpdateDocumentError, Unit] }
  • 20. FUNCTIONAL ▸ I was preparing a blog post or a talk about pure functional error handling ▸ It was about typeclasses like ApplicativeError, MonadError… (similar to how Future handles errors) ▸ I may still talk about them ▸ But suddenly….
  • 22. FUNCTIONAL ▸ So I’ll simplify and use F[Either[E,A]] for any F Monad you choose type Action[E, A] = F[Either[E, A]
  • 23. FUNCTIONAL class DocumentService( documentRepository: DocumentRepository, transactionController: TransactionController) { def saveDocumentIfNotFound(document: Document): Action[ConnectionError, Unit] = { transactionController.inTransaction { for { doc <- documentRepository.getDocument(document.id) _ <- if (doc.nonEmpty) { documentRepository.updateDocument(document) } else { documentRepository.insertDocument(document) } } yield () } } }
  • 24. FUNCTIONAL trait DocumentRepository { def getDocument(documentId: DocumentId): TxAction[ConnectionError, Option[Document]] def insertDocument(document: Document): TxAction[InsertDocumentError, Unit] def updateDocument(document: Document): TxAction[UpdateDocumentError, Unit] }
  • 25. FUNCTIONAL trait Documents[F[_]] { implicit def M: Monad[F] type Transaction type Action[E, A] = EitherT[F, E, A] // ~= F[Either[E,A]] object Action { def apply[E, A](s: F[Either[E, A]]): EitherT[F, E, A] = EitherT.fromEither(s) } type TxAction[E, A] = Kleisli[Action[E, ?], Transaction, A] // ~= Transaction => Action[E,A] object TxAction { def apply[E, A](f: Transaction => Action[E, A]): TxAction[E, A] = Kleisli[Action[E, ?], Transaction, A](f) } implicit def txActionBifunctor: Bifunctor[TxAction] = new Bifunctor[TxAction] { override def bimap[A, B, C, D](fab: TxAction[A, B])(f: A => C, g: B => D): TxAction[C, D] = TxAction { tx => fab.run(tx).bimap(f, g)} } … }
  • 28. EITHERT AND MONADTRANSFORMERS ▸ https://github.com/scalaz/scalaz/pull/1708
  • 30. FUNCTIONAL class DocumentService( documentRepository: DocumentRepository, transactionController: TransactionController) { def saveDocumentIfNotFound(document: Document): F[ConnectionError, Unit] = { transactionController.inTransaction { for { doc <- documentRepository.getDocument(document.id) _ <- if (doc.nonEmpty) { documentRepository.updateDocument(document) } else { documentRepository.insertDocument(document) } } yield () } } }
  • 31. FUNCTIONAL trait DocumentRepository { def getDocument(documentId: DocumentId): TxAction[ConnectionError, Option[Document]] def insertDocument(document: Document): TxAction[InsertDocumentError, Unit] def updateDocument(document: Document): TxAction[UpdateDocumentError, Unit] }
  • 32. FUNCTIONAL trait Documents[F[+ _, + _]] extends Transactional[F] { implicit def M[E]: Monad[F[E, ?]] class DocumentService(…) {…} trait TransactionController {…} trait DocumentRepository {…} }
  • 33. FUNCTIONAL trait Transactional[F[+_,+_]]{ implicit def B:Bitraverse[F] type Transaction type TxAction[E, A] = Kleisli[F[E, ?], Transaction, A] // ~== Transaction => F[E,A] object TxAction { def apply[E, A](f: Transaction => F[E, A]): TxAction[E, A] = Kleisli[F[E, ?], Transaction, A](f) } protected implicit val BT: Bifunctor[TxAction] = KleisiUtils.kleisliBifunctor[F,Transaction] }
  • 34.