SlideShare a Scribd company logo
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 FILE
Anushka Rai
 
functions of C++
functions of C++functions of C++
functions of C++
tarandeep_kaur
 
Fp201 unit4
Fp201 unit4Fp201 unit4
Fp201 unit4
rohassanie
 
function in c
function in cfunction in c
function in c
subam3
 
LINQ Internals - STLDODN
LINQ Internals - STLDODNLINQ Internals - STLDODN
LINQ Internals - STLDODN
Keith Dahlby
 
C++ programming function
C++ programming functionC++ programming function
C++ programming function
Vishalini Mugunen
 
Labsheet 7 FP 201
Labsheet 7 FP 201Labsheet 7 FP 201
Labsheet 7 FP 201
rohassanie
 
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
Nauman Rehman
 
FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3
rohassanie
 
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
 
CHAPTER 6
CHAPTER 6CHAPTER 6
CHAPTER 6
mohd_mizan
 
lets play with "c"..!!! :):)
lets play with "c"..!!! :):)lets play with "c"..!!! :):)
lets play with "c"..!!! :):)
Rupendra Choudhary
 
Array notes
Array notesArray notes
Array notes
Hitesh Wagle
 
Introduction to Go for Java Programmers
Introduction to Go for Java ProgrammersIntroduction to Go for Java Programmers
Introduction to Go for Java Programmers
Kalpa Pathum Welivitigoda
 
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
 
DIG1108 Lesson 6
DIG1108 Lesson 6DIG1108 Lesson 6
DIG1108 Lesson 6
vc-dig1108-fall-2013
 
Functions
FunctionsFunctions
Functions
SANTOSH RATH
 
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#
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 Berlin
Iain 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 modeling
Mario 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 modeling
Codemotion
 
Improving Correctness with Types Kats Conf
Improving Correctness with Types Kats ConfImproving Correctness with Types Kats Conf
Improving Correctness with Types Kats Conf
Iain Hull
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
RichardWarburton
 
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
Luka 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
 
Templates and Polymorphism in C++ Programming
Templates and Polymorphism in C++ ProgrammingTemplates and Polymorphism in C++ Programming
Templates and Polymorphism in C++ Programming
tafatih
 
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
saintiss
 
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
RamziFeghali
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with Types
Iain Hull
 
JavaScript
JavaScriptJavaScript
JavaScript
Bharti Gupta
 
Friendly Functional Programming
Friendly Functional ProgrammingFriendly Functional Programming
Friendly Functional Programming
Wiem Zine Elabidine
 
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
Eelco Visser
 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.ppt
ssuser823678
 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.ppt
ssuser2076d9
 
functions
functionsfunctions
functions
Makwana Bhavesh
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
Raymond Roestenburg
 
Fundamentals of functions in C program.pptx
Fundamentals of functions in C program.pptxFundamentals of functions in C program.pptx
Fundamentals of functions in C program.pptx
Chandrakant Divate
 

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)
 
Templates and Polymorphism in C++ Programming
Templates and Polymorphism in C++ ProgrammingTemplates and Polymorphism in C++ Programming
Templates and Polymorphism in C++ Programming
 
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
 
Fundamentals of functions in C program.pptx
Fundamentals of functions in C program.pptxFundamentals of functions in C program.pptx
Fundamentals of functions in C program.pptx
 

Recently uploaded

A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
kalichargn70th171
 
Project Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdfProject Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdf
Karya Keeper
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
Preparing Non - Technical Founders for Engaging a Tech Agency
Preparing Non - Technical Founders for Engaging  a  Tech AgencyPreparing Non - Technical Founders for Engaging  a  Tech Agency
Preparing Non - Technical Founders for Engaging a Tech Agency
ISH Technologies
 
ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.
Maitrey Patel
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
Patrick Weigel
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
gapen1
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
ppt on the brain chip neuralink.pptx
ppt  on   the brain  chip neuralink.pptxppt  on   the brain  chip neuralink.pptx
ppt on the brain chip neuralink.pptx
Reetu63
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...
Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...
Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...
The Third Creative Media
 
Kubernetes at Scale: Going Multi-Cluster with Istio
Kubernetes at Scale:  Going Multi-Cluster  with IstioKubernetes at Scale:  Going Multi-Cluster  with Istio
Kubernetes at Scale: Going Multi-Cluster with Istio
Severalnines
 
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom KittEnhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Peter Caitens
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 

Recently uploaded (20)

A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
 
Project Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdfProject Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdf
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
Preparing Non - Technical Founders for Engaging a Tech Agency
Preparing Non - Technical Founders for Engaging  a  Tech AgencyPreparing Non - Technical Founders for Engaging  a  Tech Agency
Preparing Non - Technical Founders for Engaging a Tech Agency
 
ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
ppt on the brain chip neuralink.pptx
ppt  on   the brain  chip neuralink.pptxppt  on   the brain  chip neuralink.pptx
ppt on the brain chip neuralink.pptx
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...
Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...
Unlock the Secrets to Effortless Video Creation with Invideo: Your Ultimate G...
 
Kubernetes at Scale: Going Multi-Cluster with Istio
Kubernetes at Scale:  Going Multi-Cluster  with IstioKubernetes at Scale:  Going Multi-Cluster  with Istio
Kubernetes at Scale: Going Multi-Cluster with Istio
 
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom KittEnhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 

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.