SlideShare ist ein Scribd-Unternehmen logo
1 von 84
Downloaden Sie, um offline zu lesen
SUPERCHARGED IMPERATIVE
PROGRAMMING WITH HASKELL
AND FP
ANUPAM JAIN
2
Hello!
3
❑ HOME PAGE

https://fpncr.github.io
❑ GETTOGETHER COMMUNITY

https://gettogether.community/fpncr/
❑ MEETUP

https://www.meetup.com/DelhiNCR-Haskell-And-
Functional-Programming-Languages-Group
❑ TELEGRAM:

https://t.me/fpncr
Functional Programming NCR
4
âť‘Type safety. Eliminates a large class of errors.
âť‘Effectful values are first class
âť‘Higher Order Patterns
âť‘Reduction in Boilerplate
âť‘Zero Cost Code Reuse
Overview
5
âť‘Order of operations matters
âť‘Contrast with functional, where the order of
operations does not matter.
Define “Imperative”
6
write "Do you want a pizza?”
if (read() == "Yes") orderPizza()
write "Should I launch missiles?”
if (read() == "Yes") launchMissiles()
Imperative is simple
7
write "Do you want a pizza?”
if (read() == "Yes") orderPizza()
write "Should I launch missiles?”
if (read() == "Yes") launchMissiles()
Imperative is simple
You REALLY DON’T
want to do these
out of order
8
do
write "Do you want a pizza?"
canOrder <- read
When (canOrder == "Yes") orderPizza
write "Should I launch missiles?"
canLaunch <- read
When (canLaunch == "Yes") launchMissiles
Functional?
9
do
write "Do you want a pizza?"
canOrder <- read
when (canOrder == "Yes") orderPizza
write "Should I launch missiles?"
canLaunch <- read
when (canLaunch == "Yes") launchMissiles
Functional?
Haskell
10
write "Do you want a pizza?" >>= _ ->
read >>= canOrderPizza ->
if (canOrderPizza == "Yes") then
orderPizza
else pure () >>= _ ->
write "Should I launch missiles?" >>= _ -
>
read >>= canLaunchMissiles ->
if (canLaunchMissiles == "Yes") then
launchMissiles
else pure ()
Functional?
11
plusOne = x -> x+1
add = x -> y -> x+y
A bit of syntax
Lambdas
12
(>>=) = effect -> handler -> ...
A bit of syntax
Operators
13
read >>= canOrderPizza -> ...
A bit of syntax
Infix Usage
14
write "Do you want a pizza?" >>= _ ->
read >>= canOrderPizza ->
if (canOrderPizza == "Yes") then
orderPizza
else pure ()
One At a Time
15
write "Should I launch missiles?" >>= _ ->
read >>= canLaunchMissiles ->
if (canLaunchMissiles == "Yes") then
launchMissiles
else pure ()
One At a Time
16
handlePizza >>= _ ->
handleMissiles
Together
17
handlePizza >>= _ ->
handleMissiles
Together
18
handlePizza :: IO ()
handlePizza = do
write "Do you want a pizza?"
canOrderPizza <- read
if (canOrderPizza == "Yes")
then orderPizza
else pure ()
Types This entire block
1. Is Effectful
2. Returns ()
19
Effectful Logic
Pure Logic
Outside World
20
❑Can’t mix effectful (imperative) code with pure
(functional) code
âť‘All branches must have the same return type
Types
21
SideEffects!!
22
“Haskell” is the world’s finest
imperative programming
language.
~Simon Peyton Jones
(Creator of Haskell)
23
So How is Haskell
The Best Imperative
Programming
Language?
24
❑We don’t launch nukes without ordering pizza
Change Requirements
25
handlePizza :: IO Bool
handlePizza = do
write "Do you want a pizza?"
canOrderPizza <- read
if (canOrderPizza == "Yes")
then orderPizza >> pure true
else pure false
Types
26
do
pizzaOrdered <- handlePizza
if pizzaOrdered
then handleMissiles
else pure ()
With Changed
Requirements
27
âť‘Ask the user a bunch of questions
âť‘Then perform a bunch of actions
Reorder?
28
Must Rearchitect
do
write "Do you want a pizza?"
canOrder <- read
write "Should I launch missiles?"
canLaunch <- read
when (canOrder == "Yes") orderPizza
when (canLaunch == "Yes") launchMissiles
29
Must Rearchitect
do
write "Do you want a pizza?"
canOrder <- read
write "Should I launch missiles?"
canLaunch <- read
when (canOrder == "Yes") orderPizza
when (canLaunch == "Yes") launchMissiles
But we have lost
the separation
between
Ordering pizza
and Launching nukes
30
We Need
âť‘Define complex flows with user input and a final
effect to be performed
âť‘To compose these flows without boilerplate
âť‘Be able to run the final effects together at the end
of all user input
31
Desired Abstraction
handlePizza = ...
handleNukes = ...
do
handlePizza
handleNukes
We ask questions in this order,
but the final effect of ordering pizza
and launching nukes should only
happen together at the end
32
Must Rearchitect
handlePizza = do
write "Do you want a pizza?"
canOrder <- read
return $
when (canOrder == "Yes") orderPizza
33
Must Rearchitect
handlePizza :: IO (IO ())
handlePizza = do
write "Do you want a pizza?"
canOrder <- read
return $
when (canOrder == "Yes") orderPizza
Return value is a CLOSURE
Captures `canOrder`
34
Must Rearchitect
handleNukes :: IO (IO ())
handleNukes = do
write “Should I launch nukes?"
canLaunch <- read
return $
when (canLaunch == "Yes") launchNukes
Return value is a CLOSURE
Captures `canLaunch`
35
Compose together
do
pizzaEffect <- handlePizza
nukeEffect <- handleNukes
pizzaEffect

nukeEffect
36
Generalises?
This looks very boilerplaty
do
pizzaEffect <- handlePizza
nukeEffect <- handleNukes
...
pizzaEffect

nukeEffect
...
37
Desired Interface
finalEffect =

handlePizza AND

handleNukes AND
...
38
And Allow A Way to
specify “No Effects”
finalEffect = emptyEffects
39
Looks Like a Monoid!
class Monoid M where
empty :: M

(<>) :: M -> M -> M
40
IO already is a
Monoid!
âť‘What happens when we do the following?
handlePizza <> handleNukes
41
IO already is a
Monoid!
instance Monoid a => Monoid (IO a) where
empty = pure empty
f <> g = do
a <- f
b <- g
pure (a <> b)
42
IO already is a
Monoid!
instance Monoid a => Monoid (IO a) where
empty = pure empty
f <> g = do
a <- f
b <- g
pure (a <> b)
First perform individual effects
43
IO already is a
Monoid!
instance Monoid a => Monoid (IO a) where
empty = pure empty
f <> g = do
a <- f
b <- g
pure (a <> b) Then Join the results
As Monoids
44
IO already is a
Monoid!
âť‘So this does the right thing!
do
finalEffects <- handlePizza <> handleNukes
finalEffects
45
This is also a pattern
join :: Monad M => M (M a) -> M a
join :: IO (IO a) -> IO a
join (handlePizza <> handleNukes)
46
No Boilerplate!
join :: Monad M => M (M a) -> M a
join :: IO (IO a) -> IO a
join (handlePizza <> handleNukes)
47
Final Code

handlePizza
handlePizza :: IO (IO ())
handlePizza = do
write "Do you want a pizza?"
canOrder <- read
return $
when (canOrder == "Yes") orderPizza
48
Final Code

handleNukes
handleNukes :: IO (IO ())
handleNukes = do
write “Should I launch nukes?"
canLaunch <- read
return $
when (canLaunch == "Yes") launchNukes
49
Final Code

Combine flows together
join (handlePizza <> handleNukes <> ...)
join (mappend [ handlePizza
, handleNukes
...
])
Or Perhaps
50
❑We don’t launch nukes without ordering pizza
❑We don’t order pizza when not launching nukes
Change Requirements
Again
51
Must Rearchitect
do
write "Do you want a pizza?"
canOrder <- read
write "Should I launch missiles?"
canLaunch <- read
when (canOrder == “Yes" && canLaunch ==
"Yes") (orderPizza >> launchMissiles)
52
Must Rearchitect
do
write "Do you want a pizza?"
canOrder <- read
write "Should I launch missiles?"
canLaunch <- read
when (canOrder == “Yes" && canLaunch ==
"Yes") (orderPizza >> launchMissiles)
Business Logic
53
A General Pattern
do
write “Question 1 ...”
answer1 <- read
...
when (validates answer1 ...)
performAllEffects
54
We Need
âť‘Define complex flows with user input and a final
effect to be performed
âť‘To compose these flows without boilerplate
âť‘Call a function on all the user input to determine if
we should perform the final effects.
âť‘Be able to run the final effects together at the end
of all user input
55
Can we do this with
Monoids?
do
finalEffects <- handlePizza <> handleNukes
finalEffects
âť‘We abstracted away the captured variables
âť‘Now all we can do is run the final composed effect
We can’t access `canOrder` or `canLaunch` here
56
FP Gives you
Granularly
Powerful
Abstractions
âť‘Monads are too powerful (i.e. boilerplate)
âť‘Monoids abstract away too much
âť‘Need something in the middle
57
Let's work through this
data Ret a = Ret
{ input :: a
, effect :: IO ()
}
âť‘Return the final effect, AND the user input
âť‘Parameterise User Input as `a`
58
Let's work through this
handlePizza :: IO (Ret Boolean)
handlePizza = do
write "Do you want a pizza?"
canOrder <- read
return $ Ret canOrder $
when (canOrder == "Yes") orderPizza
59
Compose Effects
do
retPizza <- handlePizza
retNuke <- handleNuke
when valid (input retPizza) (input
retNuke) do
effect retPizza
effect retNuke
60
Compose Effects
do
retPizza <- handlePizza
retNuke <- handleNuke
when valid (input retPizza) (input
retNuke) do
effect retPizza
effect retNuke
UGH! Boilerplate!
61
Compose Effects
do
retPizza <- handlePizza
retNuke <- handleNuke
let go = valid (input retPizza) (input
retNuke)
when go do
effect retPizza
effect retNuke
62
Compose Effects
do
retPizza <- handlePizza
retNuke <- handleNuke
let go = valid (input retPizza) (input
retNuke)
when go do
effect retPizza
effect retNuke
Applicative!
63
IO is an Applicative
instance Applicative IO where
f <*> a = do
f' <- f
a' <- a
pure (f' a')
64
Try to Use Applicative IO
do
go <- valid
<$> (input <$> handlePizza)
<*> (input <$> handleNuke)
when go do
effect ??retPizza
effect ??retNuke
65
Dial Back a Little
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let go = valid
<$> input retPizza
<*> input retNuke
when go do
effect retPizza
effect retNuke
66
Perhaps a try a
different abstraction
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let go = valid
<$> input retPizza
<*> input retNuke
when go do
effect retPizza
effect retNuke
This is a common pattern
Can we abstract this?
67
Running a Return value
data Ret a = Ret
{ input :: a
, effect :: IO ()}
runRet :: Ret Bool -> IO ()
runRet (Ret b e) = when b e
68
More trouble than its
worth?
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let go = valid
<$> input retPizza
<*> input retNuke
runRet ??? We need to Compose a Ret
To be able to run it
69
However!
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let go = valid
<$> input retPizza
<*> input retNuke
runRet ???
This could return a
Ret instead!
70
Combining Return values
data Ret a = Ret
{ input :: a
, effect :: IO ()}
instance Functor Ret where
fmap f (Ret a e) = Ret (f a) e
instance Applicative Ret where
Ret f e1 <*> Ret a e2 =
Ret (f a) (e1 <> e2)
71
Less Boilerplate!
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let ret = valid
<$> retPizza
<*> retNuke
runRet ret
72
Hmm, Still Boilerplatey
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let ret = valid
<$> retPizza
<*> retNuke
runRet ret
Two Successive
Applicatives
73
Hmm, Still Boilerplatey
do
(retPizza, retNuke) <- (,)
<$> handlePizza
<*> handleNuke
let ret = valid
<$> retPizza
<*> retNuke
runRet ret
Combine Effectful

IO
Combine Effectful

Ret
74
Compose Applicatives?
data IO a = ...
data Ret a = Ret
{ input :: a
, effect :: IO ()}
type Flow a = IO (Ret a)
We need an Applicative instance for Flow
75
Applicatives Compose!
Import Data.Functor.Compose
type Compose f g a = Compose (f (g a))
type Flow a = Compose IO Ret a
76
Applicatives Compose!
instance (Applicative f, Applicative g)
=> Applicative (Compose f g) where
Compose f <*> Compose x =
Compose (liftA2 (<*>) f x)
77
Running Compose
runRet :: Ret Bool -> IO ()
runRet (Ret b e) = when b e
runFlow :: Compose IO Ret Bool -> IO ()
runFlow (Compose e) = e >>= runRet
78
Defining Flows
handlePizza :: Flow Boolean
handlePizza = Compose $ do
write "Do you want a pizza?"
canOrder <- read
return $ Ret canOrder $
when (canOrder == "Yes") orderPizza
79
Composing Flow With
Business Logic
valid
<$> handlePizza
<*> handleNukes
<*> ...
80
No Boilerplate
runFlow $ valid
<$> handlePizza
<*> handleNuke
81
âť‘Type safety. Eliminates a large class of errors.
âť‘Effectful values are first class
âť‘Higher Order Patterns
âť‘Reduction in Boilerplate
âť‘Zero Cost Code Reuse
Takeaways
82
SideEffects!!
83
Besties!!
84
Thank You
Questions?

Weitere ähnliche Inhalte

Mehr von Tech Triveni

Semi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text DataSemi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text DataTech Triveni
 
Finding the best solution for Image Processing
Finding the best solution for Image ProcessingFinding the best solution for Image Processing
Finding the best solution for Image ProcessingTech Triveni
 
Proximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data PlatformsProximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data PlatformsTech Triveni
 
Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...Tech Triveni
 
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)Tech Triveni
 
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...Tech Triveni
 
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)Tech Triveni
 
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...Tech Triveni
 
UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)Tech Triveni
 
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)Tech Triveni
 
Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Tech Triveni
 
Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...Tech Triveni
 
Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Tech Triveni
 
Augmentation of bids for programmatic ad auctions @ real time with the power ...
Augmentation of bids for programmatic ad auctions @ real time with the power ...Augmentation of bids for programmatic ad auctions @ real time with the power ...
Augmentation of bids for programmatic ad auctions @ real time with the power ...Tech Triveni
 
Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...
Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...
Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...Tech Triveni
 

Mehr von Tech Triveni (15)

Semi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text DataSemi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text Data
 
Finding the best solution for Image Processing
Finding the best solution for Image ProcessingFinding the best solution for Image Processing
Finding the best solution for Image Processing
 
Proximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data PlatformsProximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data Platforms
 
Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...
 
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
 
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
 
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
 
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
 
UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)
 
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
 
Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)
 
Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...
 
Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)
 
Augmentation of bids for programmatic ad auctions @ real time with the power ...
Augmentation of bids for programmatic ad auctions @ real time with the power ...Augmentation of bids for programmatic ad auctions @ real time with the power ...
Augmentation of bids for programmatic ad auctions @ real time with the power ...
 
Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...
Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...
Programmable Decision Tree @Scale for Programmatic Media Buying - Rohit Sriva...
 

KĂĽrzlich hochgeladen

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel AraĂşjo
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 

KĂĽrzlich hochgeladen (20)

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 

Supercharged imperative programming with Haskell and Functional Programming

  • 1. SUPERCHARGED IMPERATIVE PROGRAMMING WITH HASKELL AND FP ANUPAM JAIN
  • 3. 3 âť‘ HOME PAGE
 https://fpncr.github.io âť‘ GETTOGETHER COMMUNITY
 https://gettogether.community/fpncr/ âť‘ MEETUP
 https://www.meetup.com/DelhiNCR-Haskell-And- Functional-Programming-Languages-Group âť‘ TELEGRAM:
 https://t.me/fpncr Functional Programming NCR
  • 4. 4 âť‘Type safety. Eliminates a large class of errors. âť‘Effectful values are first class âť‘Higher Order Patterns âť‘Reduction in Boilerplate âť‘Zero Cost Code Reuse Overview
  • 5. 5 âť‘Order of operations matters âť‘Contrast with functional, where the order of operations does not matter. Define “Imperative”
  • 6. 6 write "Do you want a pizza?” if (read() == "Yes") orderPizza() write "Should I launch missiles?” if (read() == "Yes") launchMissiles() Imperative is simple
  • 7. 7 write "Do you want a pizza?” if (read() == "Yes") orderPizza() write "Should I launch missiles?” if (read() == "Yes") launchMissiles() Imperative is simple You REALLY DON’T want to do these out of order
  • 8. 8 do write "Do you want a pizza?" canOrder <- read When (canOrder == "Yes") orderPizza write "Should I launch missiles?" canLaunch <- read When (canLaunch == "Yes") launchMissiles Functional?
  • 9. 9 do write "Do you want a pizza?" canOrder <- read when (canOrder == "Yes") orderPizza write "Should I launch missiles?" canLaunch <- read when (canLaunch == "Yes") launchMissiles Functional? Haskell
  • 10. 10 write "Do you want a pizza?" >>= _ -> read >>= canOrderPizza -> if (canOrderPizza == "Yes") then orderPizza else pure () >>= _ -> write "Should I launch missiles?" >>= _ - > read >>= canLaunchMissiles -> if (canLaunchMissiles == "Yes") then launchMissiles else pure () Functional?
  • 11. 11 plusOne = x -> x+1 add = x -> y -> x+y A bit of syntax Lambdas
  • 12. 12 (>>=) = effect -> handler -> ... A bit of syntax Operators
  • 13. 13 read >>= canOrderPizza -> ... A bit of syntax Infix Usage
  • 14. 14 write "Do you want a pizza?" >>= _ -> read >>= canOrderPizza -> if (canOrderPizza == "Yes") then orderPizza else pure () One At a Time
  • 15. 15 write "Should I launch missiles?" >>= _ -> read >>= canLaunchMissiles -> if (canLaunchMissiles == "Yes") then launchMissiles else pure () One At a Time
  • 16. 16 handlePizza >>= _ -> handleMissiles Together
  • 17. 17 handlePizza >>= _ -> handleMissiles Together
  • 18. 18 handlePizza :: IO () handlePizza = do write "Do you want a pizza?" canOrderPizza <- read if (canOrderPizza == "Yes") then orderPizza else pure () Types This entire block 1. Is Effectful 2. Returns ()
  • 20. 20 âť‘Can’t mix effectful (imperative) code with pure (functional) code âť‘All branches must have the same return type Types
  • 22. 22 “Haskell” is the world’s finest imperative programming language. ~Simon Peyton Jones (Creator of Haskell)
  • 23. 23 So How is Haskell The Best Imperative Programming Language?
  • 24. 24 âť‘We don’t launch nukes without ordering pizza Change Requirements
  • 25. 25 handlePizza :: IO Bool handlePizza = do write "Do you want a pizza?" canOrderPizza <- read if (canOrderPizza == "Yes") then orderPizza >> pure true else pure false Types
  • 26. 26 do pizzaOrdered <- handlePizza if pizzaOrdered then handleMissiles else pure () With Changed Requirements
  • 27. 27 âť‘Ask the user a bunch of questions âť‘Then perform a bunch of actions Reorder?
  • 28. 28 Must Rearchitect do write "Do you want a pizza?" canOrder <- read write "Should I launch missiles?" canLaunch <- read when (canOrder == "Yes") orderPizza when (canLaunch == "Yes") launchMissiles
  • 29. 29 Must Rearchitect do write "Do you want a pizza?" canOrder <- read write "Should I launch missiles?" canLaunch <- read when (canOrder == "Yes") orderPizza when (canLaunch == "Yes") launchMissiles But we have lost the separation between Ordering pizza and Launching nukes
  • 30. 30 We Need âť‘Define complex flows with user input and a final effect to be performed âť‘To compose these flows without boilerplate âť‘Be able to run the final effects together at the end of all user input
  • 31. 31 Desired Abstraction handlePizza = ... handleNukes = ... do handlePizza handleNukes We ask questions in this order, but the final effect of ordering pizza and launching nukes should only happen together at the end
  • 32. 32 Must Rearchitect handlePizza = do write "Do you want a pizza?" canOrder <- read return $ when (canOrder == "Yes") orderPizza
  • 33. 33 Must Rearchitect handlePizza :: IO (IO ()) handlePizza = do write "Do you want a pizza?" canOrder <- read return $ when (canOrder == "Yes") orderPizza Return value is a CLOSURE Captures `canOrder`
  • 34. 34 Must Rearchitect handleNukes :: IO (IO ()) handleNukes = do write “Should I launch nukes?" canLaunch <- read return $ when (canLaunch == "Yes") launchNukes Return value is a CLOSURE Captures `canLaunch`
  • 35. 35 Compose together do pizzaEffect <- handlePizza nukeEffect <- handleNukes pizzaEffect
 nukeEffect
  • 36. 36 Generalises? This looks very boilerplaty do pizzaEffect <- handlePizza nukeEffect <- handleNukes ... pizzaEffect
 nukeEffect ...
  • 38. 38 And Allow A Way to specify “No Effects” finalEffect = emptyEffects
  • 39. 39 Looks Like a Monoid! class Monoid M where empty :: M
 (<>) :: M -> M -> M
  • 40. 40 IO already is a Monoid! âť‘What happens when we do the following? handlePizza <> handleNukes
  • 41. 41 IO already is a Monoid! instance Monoid a => Monoid (IO a) where empty = pure empty f <> g = do a <- f b <- g pure (a <> b)
  • 42. 42 IO already is a Monoid! instance Monoid a => Monoid (IO a) where empty = pure empty f <> g = do a <- f b <- g pure (a <> b) First perform individual effects
  • 43. 43 IO already is a Monoid! instance Monoid a => Monoid (IO a) where empty = pure empty f <> g = do a <- f b <- g pure (a <> b) Then Join the results As Monoids
  • 44. 44 IO already is a Monoid! âť‘So this does the right thing! do finalEffects <- handlePizza <> handleNukes finalEffects
  • 45. 45 This is also a pattern join :: Monad M => M (M a) -> M a join :: IO (IO a) -> IO a join (handlePizza <> handleNukes)
  • 46. 46 No Boilerplate! join :: Monad M => M (M a) -> M a join :: IO (IO a) -> IO a join (handlePizza <> handleNukes)
  • 47. 47 Final Code
 handlePizza handlePizza :: IO (IO ()) handlePizza = do write "Do you want a pizza?" canOrder <- read return $ when (canOrder == "Yes") orderPizza
  • 48. 48 Final Code
 handleNukes handleNukes :: IO (IO ()) handleNukes = do write “Should I launch nukes?" canLaunch <- read return $ when (canLaunch == "Yes") launchNukes
  • 49. 49 Final Code
 Combine flows together join (handlePizza <> handleNukes <> ...) join (mappend [ handlePizza , handleNukes ... ]) Or Perhaps
  • 50. 50 âť‘We don’t launch nukes without ordering pizza âť‘We don’t order pizza when not launching nukes Change Requirements Again
  • 51. 51 Must Rearchitect do write "Do you want a pizza?" canOrder <- read write "Should I launch missiles?" canLaunch <- read when (canOrder == “Yes" && canLaunch == "Yes") (orderPizza >> launchMissiles)
  • 52. 52 Must Rearchitect do write "Do you want a pizza?" canOrder <- read write "Should I launch missiles?" canLaunch <- read when (canOrder == “Yes" && canLaunch == "Yes") (orderPizza >> launchMissiles) Business Logic
  • 53. 53 A General Pattern do write “Question 1 ...” answer1 <- read ... when (validates answer1 ...) performAllEffects
  • 54. 54 We Need âť‘Define complex flows with user input and a final effect to be performed âť‘To compose these flows without boilerplate âť‘Call a function on all the user input to determine if we should perform the final effects. âť‘Be able to run the final effects together at the end of all user input
  • 55. 55 Can we do this with Monoids? do finalEffects <- handlePizza <> handleNukes finalEffects âť‘We abstracted away the captured variables âť‘Now all we can do is run the final composed effect We can’t access `canOrder` or `canLaunch` here
  • 56. 56 FP Gives you Granularly Powerful Abstractions âť‘Monads are too powerful (i.e. boilerplate) âť‘Monoids abstract away too much âť‘Need something in the middle
  • 57. 57 Let's work through this data Ret a = Ret { input :: a , effect :: IO () } âť‘Return the final effect, AND the user input âť‘Parameterise User Input as `a`
  • 58. 58 Let's work through this handlePizza :: IO (Ret Boolean) handlePizza = do write "Do you want a pizza?" canOrder <- read return $ Ret canOrder $ when (canOrder == "Yes") orderPizza
  • 59. 59 Compose Effects do retPizza <- handlePizza retNuke <- handleNuke when valid (input retPizza) (input retNuke) do effect retPizza effect retNuke
  • 60. 60 Compose Effects do retPizza <- handlePizza retNuke <- handleNuke when valid (input retPizza) (input retNuke) do effect retPizza effect retNuke UGH! Boilerplate!
  • 61. 61 Compose Effects do retPizza <- handlePizza retNuke <- handleNuke let go = valid (input retPizza) (input retNuke) when go do effect retPizza effect retNuke
  • 62. 62 Compose Effects do retPizza <- handlePizza retNuke <- handleNuke let go = valid (input retPizza) (input retNuke) when go do effect retPizza effect retNuke Applicative!
  • 63. 63 IO is an Applicative instance Applicative IO where f <*> a = do f' <- f a' <- a pure (f' a')
  • 64. 64 Try to Use Applicative IO do go <- valid <$> (input <$> handlePizza) <*> (input <$> handleNuke) when go do effect ??retPizza effect ??retNuke
  • 65. 65 Dial Back a Little do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let go = valid <$> input retPizza <*> input retNuke when go do effect retPizza effect retNuke
  • 66. 66 Perhaps a try a different abstraction do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let go = valid <$> input retPizza <*> input retNuke when go do effect retPizza effect retNuke This is a common pattern Can we abstract this?
  • 67. 67 Running a Return value data Ret a = Ret { input :: a , effect :: IO ()} runRet :: Ret Bool -> IO () runRet (Ret b e) = when b e
  • 68. 68 More trouble than its worth? do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let go = valid <$> input retPizza <*> input retNuke runRet ??? We need to Compose a Ret To be able to run it
  • 69. 69 However! do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let go = valid <$> input retPizza <*> input retNuke runRet ??? This could return a Ret instead!
  • 70. 70 Combining Return values data Ret a = Ret { input :: a , effect :: IO ()} instance Functor Ret where fmap f (Ret a e) = Ret (f a) e instance Applicative Ret where Ret f e1 <*> Ret a e2 = Ret (f a) (e1 <> e2)
  • 71. 71 Less Boilerplate! do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let ret = valid <$> retPizza <*> retNuke runRet ret
  • 72. 72 Hmm, Still Boilerplatey do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let ret = valid <$> retPizza <*> retNuke runRet ret Two Successive Applicatives
  • 73. 73 Hmm, Still Boilerplatey do (retPizza, retNuke) <- (,) <$> handlePizza <*> handleNuke let ret = valid <$> retPizza <*> retNuke runRet ret Combine Effectful
 IO Combine Effectful
 Ret
  • 74. 74 Compose Applicatives? data IO a = ... data Ret a = Ret { input :: a , effect :: IO ()} type Flow a = IO (Ret a) We need an Applicative instance for Flow
  • 75. 75 Applicatives Compose! Import Data.Functor.Compose type Compose f g a = Compose (f (g a)) type Flow a = Compose IO Ret a
  • 76. 76 Applicatives Compose! instance (Applicative f, Applicative g) => Applicative (Compose f g) where Compose f <*> Compose x = Compose (liftA2 (<*>) f x)
  • 77. 77 Running Compose runRet :: Ret Bool -> IO () runRet (Ret b e) = when b e runFlow :: Compose IO Ret Bool -> IO () runFlow (Compose e) = e >>= runRet
  • 78. 78 Defining Flows handlePizza :: Flow Boolean handlePizza = Compose $ do write "Do you want a pizza?" canOrder <- read return $ Ret canOrder $ when (canOrder == "Yes") orderPizza
  • 79. 79 Composing Flow With Business Logic valid <$> handlePizza <*> handleNukes <*> ...
  • 80. 80 No Boilerplate runFlow $ valid <$> handlePizza <*> handleNuke
  • 81. 81 âť‘Type safety. Eliminates a large class of errors. âť‘Effectful values are first class âť‘Higher Order Patterns âť‘Reduction in Boilerplate âť‘Zero Cost Code Reuse Takeaways