SlideShare a Scribd company logo
1 of 184
Download to read offline
DotNext 2019
The Power Of Composition
@ScottWlaschin
fsharpforfunandprofit.com
The Power Of Composition
1. The philosophy of composition
2. Ideas of functional programming
– Functions and how to compose them
– Types and how to compose them
3. Composition in practice
– Roman Numerals
– FizzBuzz gone carbonated
– Uh oh, monads!
– A web service
THE PHILOSOPHY OF
COMPOSITION
Prerequisites for
understanding composition
• You must have been a child at some point
• You must have played with Lego
• You must have played with toy trains
Lego
Philosophy
Lego Philosophy
1. All pieces are designed to be connected
2. The pieces are reusable in many contexts
3. Connect two pieces together and get
another "piece" that can still be connected
All pieces are designed to be connected
The pieces are reusable in different contexts
Connect two pieces together and
get another "piece" that can still be connected
Make big things from small things in the same way
Wooden Railway Track Philosophy
1. All pieces are designed to be connected
2. The pieces are reusable in many contexts
3. Connect two pieces together and get
another "piece" that can still be connected
All pieces are designed to be connected
The pieces are reusable in different contexts
Connect two pieces together and get
another "piece" that can still be connected
You can keep adding and adding.
Make big things from small things in the same way
If you understand Lego and wooden
railways, then you know
everything about composition!
THE IDEAS OF
FUNCTIONAL PROGRAMMING
Four ideas behind FP
Function
3.Types are not classes
1. Functions are things
2. Build bigger functions using
composition
4. Build bigger types using
composition
FP idea #1:
Functions are things
Function
The Tunnel of
Transformation
Function
apple -> banana
A function is a thing which
transforms inputs to outputs
A function is a standalone thing,
not attached to a class
A function is a standalone thing,
not attached to a class
It can be used for inputs and outputs
of other functions
A function can be an output thing
input
output
A function can be an input thing
input output
A function can be a parameter
input
output
input output
FP idea #2:
Build bigger functions
using composition
Function 1
apple -> banana
Function 2
banana -> cherry
>>
Function 1
apple -> banana
Function 2
banana -> cherry
New Function
apple -> cherry
Can't tell it was built
from smaller functions!
Where did the banana go?
Function composition in F# and C#
using the "piping" approach
int add1(int x) => x + 1;
int times2(int x) => x * 2;
int square(int x) => x * x;
add1(5); // = 6
times2(add1(5)); // = 12
square(times2(add1(5))); // = 144
Nested function calls
can be confusing if too deep
add15 6 times2 12 square 144
5 |> add1 // = 6
5 |> add1 |> times2 // = 12
5 |> add1 |> times2 |> square // = 144
add1 times2 square5 6 12 144
F# example
add1 times2 square5 6 12 144
5.Pipe(add1);
5.Pipe(add1).Pipe(times2);
5.Pipe(add1).Pipe(times2).Pipe(square);
C# example
Building big things from functions
It's compositions all the way up
Low-level operation
ToUpper
stringstring
Low-level operation
Service
AddressValidator
A “Service” is just like a microservice
but without the "micro" in front
Validation
Result
Address
Low-level operation Low-level operation
Service
Use-case
UpdateProfileData
ChangeProfile
Result
ChangeProfile
Request
Service Service
Use-case
Web application
Http
Response
Http
Request
Use-case Use-case
Http
Response
Http
Request
Even for complex applications,
data flows only in one direction
FP idea #3:
Types are not classes
So, what is a type then?
A type is a just a name
for a set of things
Set of
valid inputs
Set of
valid outputs
Function
Set of
valid inputs
Set of
valid outputs
Function
1
2
3
4
5
6
This is type
"integer"
A type is a just a name
for a set of things
Set of
valid inputs
Set of
valid outputs
Function
This is type
"string"
"abc"
"but"
"cobol"
"double"
"end"
"float"
A type is a just a name
for a set of things
Set of
valid inputs
Set of
valid outputs
Function
This is type
"Person"
Donna Roy
Javier Mendoza
Nathan Logan
Shawna Ingram
Abel Ortiz
Lena Robbins
GordonWood
A type is a just a name
for a set of things
Set of
valid inputs
Set of
valid outputs
Function
This is type
"Fruit"
A type is a just a name
for a set of things
Set of
valid inputs
Set of
valid outputs
Function
This is a type of
Fruit->Fruit functions
A type is a just a name
for a set of things
FP idea #4:
Types can be composed too
Algebraic type system
Bigger types are built from smaller types by:
Composing with “AND”
Composing with “OR”
FruitSalad =
AND AND
Compose with “AND”
Compose with “AND”
enum AppleVariety { Red, Green }
enum BananaVariety { Yellow, Brown }
enum CherryVariety { Tart, Sweet }
struct FruitSalad
{
AppleVariety Apple;
BananaVariety Banana;
CherryVariety Cherry;
}
C# example
Apple AND
Banana AND
Cherry
Compose with “AND”
type AppleVariety = Red | Green
type BananaVariety = Yellow | Brown
type CherryVariety = Tart | Sweet
type FruitSalad = {
Apple: AppleVariety
Banana: BananaVariety
Cherry: CherryVariety
}
F# example
Snack = OR OR
Compose with “OR”
type Snack =
| Apple of AppleVariety
| Banana of BananaVariety
| Cherry of CherryVariety
A real world example
of composing types
Some requirements:
We accept three forms of payment:
Cash, Paypal, or CreditCard.
For Cash we don't need any extra information
For Paypal we need an email address
For Cards we need a card type and card number
interface IPaymentMethod
{..}
class Cash() : IPaymentMethod
{..}
class Paypal(string emailAddress): IPaymentMethod
{..}
class Card(string cardType, string cardNo) : IPaymentMethod
{..}
In OO design you would probably implement it as an
interface and a set of subclasses, like this:
type EmailAddress = string
type CardNumber = string
In F# you would probably implement by composing
types, like this:
type EmailAddress = ...
type CardNumber = …
type CardType = Visa | Mastercard
type CreditCardInfo = {
CardType : CardType
CardNumber : CardNumber
}
type EmailAddress = ...
type CardNumber = ...
type CardType = ...
type CreditCardInfo = ...
type PaymentMethod =
| Cash
| PayPal of EmailAddress
| Card of CreditCardInfo
type EmailAddress = ...
type CardNumber = ...
type CardType = ...
type CreditCardInfo = ...
type PaymentMethod =
| Cash
| PayPal of EmailAddress
| Card of CreditCardInfo
type PaymentAmount = decimal
type Currency = EUR | USD | RUB
type EmailAddress = ...
type CardNumber = ...
type CardType = ...
type CreditCardInfo = ...
type PaymentMethod =
| Cash
| PayPal of EmailAddress
| Card of CreditCardInfo
type PaymentAmount = decimal
type Currency = EUR | USD | RUB
type Payment = {
Amount : PaymentAmount
Currency : Currency
Method : PaymentMethod }
type EmailAddress = ...
type CardNumber = ...
type CardType = ...
type CreditCardInfo = ...
type PaymentMethod =
| Cash
| PayPal of EmailAddress
| Card of CreditCardInfo
type PaymentAmount = decimal
type Currency = EUR | USD | RUB
type Payment = {
Amount : PaymentAmount
Currency : Currency
Method : PaymentMethod }
Composable types can be used as
executable documentation
type Deal = Deck -> (Deck * Card)
type PickupCard = (Hand * Card) -> Hand
type Suit = Club | Diamond | Spade | Heart
type Rank = Two | Three | Four | Five | Six | Seven | Eight
| Nine | Ten | Jack | Queen | King | Ace
type Card = { Suit:Suit; Rank:Rank }
type Hand = Card list
type Deck = Card list
type Player = {Name:string; Hand:Hand}
type Game = { Deck:Deck; Players:Player list }
The domain on one screen!
type CardType = Visa | Mastercard
type CardNumber = string
type EmailAddress = string
type PaymentMethod =
| Cash
| PayPal of EmailAddress
| Card of CreditCardInfo
| Bitcoin of BitcoinAddress
A big topic and not enough time  
More on DDD and designing with types at
fsharpforfunandprofit.com/ddd
Composition in practice:
Time for some real examples!
COMPOSITION WITH PIPING
(ROMAN NUMERALS)
Technique #1
To Roman Numerals
• Task: How to convert an arabic integer
to roman numerals?
• 5 => "V"
• 12 => "XII"
• 107 => "CVII"
To Roman Numerals
To Roman Numerals
• Use the "tally" approach
– Start with N copies of "I"
– Replace five "I"s with a "V"
– Replace two "V"s with a "X"
– Replace five "X"s with a "L"
– Replace two "L"s with a "C"
– etc
To Roman Numerals
number
etc
Replicate "I"
Replace_IIIII_V
Replace_VV_X
Replace_XXXXX_L
string ToRomanNumerals(int number)
{
// define a helper function for each step
string replace_IIIII_V(string s) =>
s.Replace("IIIII", "V");
string replace_VV_X(string s) =>
s.Replace("VV", "X");
string replace_XXXXX_L(string s) =>
s.Replace("XXXXX", "L");
string replace_LL_C(string s) =>
s.Replace("LL", "C");
// then combine them using piping
return new string('I', number)
.Pipe(replace_IIIII_V)
.Pipe(replace_VV_X)
.Pipe(replace_XXXXX_L)
.Pipe(replace_LL_C);
}
C# example
let toRomanNumerals number =
// define a helper function for each step
let replace_IIIII_V str =
replace "IIIII" "V" str
let replace_VV_X str =
replace "VV" "X" str
let replace_XXXXX_L str =
replace "XXXXX" "L" str
let replace_LL_C str =
replace "LL" "C" str
// then combine them using piping
String.replicate number "I"
|> replace_IIIII_V
|> replace_VV_X
|> replace_XXXXX_L
|> replace_LL_C
F# example
IT'S NOT ALWAYSTHIS
EASY…
function A function BCompose
function A function B
function A and B
Easy!
... But here is a challenge
function AInput Output
function B
Input 1 Output
Input 2
function AInput Output
function B
Input 1 Output
Input 2
Challenge #1: How can
we compose these?

COMPOSITIONWITH CURRYING
(ROMAN NUMERALS)
Technique #2
The Replace function
oldValue outputString
newValue
inputString
Replace
Uh-oh! Composition problem
Replace I / V Replace V / X Replace X / L 
Bad news:
Composition patterns
only work for functions that
have one parameter! 
Good news!
Every function can be turned into
a one parameter function 
Haskell Curry
We named this technique after him
Input A
Uncurried
Function
Input B
Output C
Curried
Function
Input A
Intermediate
Function
Output CInput B
What is currying?
after currying
Function as output
Input A
Uncurried
Function
Input B
Output C
Curried
Function
Input A
Intermediate
Function
Output CInput B
What is currying?
One input One input
Currying means that *every* function can be converted
to a series of one input functions
Replace
Before currying
input.Replace(oldValue, newValue);
string output
Replace
Old New
Old
New
After currying
Func<string,string> replace(string oldVal, string newVal) =>
input => input.Replace(oldVal, newVal);
Replace
Old New
Old
New
After currying
Func<string,string> replace(string oldVal, string newVal) =>
input => input.Replace(oldVal, newVal);
Func<string,string> replace(string oldVal, string newVal) =>
input => input.Replace(oldVal, newVal);
Replace
Old New
Old
New
After currying
This lambda (function) is returned
one-parameter
function
string ToRomanNumerals(int number)
{
// define a general helper function
Func<string,string> replace(
string oldValue, string newValue) =>
input => input.Replace(oldValue, newValue);
// then use piping
return new string('I', number)
.Pipe(replace("IIIII","V"))
.Pipe(replace("VV","X"))
.Pipe(replace("XXXXX","L"))
.Pipe(replace("LL","C"));
}
C# example
let toRomanNumerals number =
// no helper function needed.
// currying occurs automatically in F#
// combine using piping
String.replicate number "I"
|> replace "IIIII" "V"
|> replace "VV" "X"
|> replace "XXXXX" "L"
|> replace "LL" "C"
F# example
let toRomanNumerals number =
// no helper function needed.
// currying occurs automatically in F#
// combine using piping
String.replicate number "I"
|> replace "IIIII" "V"
|> replace "VV" "X"
|> replace "XXXXX" "L"
|> replace "LL" "C"
Only 2 of the 3
parameters are passed ?
Partial Application
Partial Application
let add x y = x + y
let multiply x y = x * y
5
|> add 2
|> multiply 3
Piping provides the missing argument
partial application
Partial Application
Replace ReplaceOldNew
Old New
Old
New
String.replicate number "I"
|> replace "IIIII" "V"
|> replace "VV" "X"
|> replace "XXXXX" "L"
|> replace "LL" "C"
Only 2 parameters
passed in
Piping provides the missing argument
Pipelines
are extensible
let toRomanNumerals number =
String.replicate number "I"
|> replace "IIIII" "V"
|> replace "VV" "X"
|> replace "XXXXX" "L"
|> replace "LL" "C"
Composable => extensible
// can easily add new segments to the pipeline
|> replace "VIIII" "IX"
|> replace "IIII" "IV"
|> replace "LXXXX" "XC"
functionInput Output
function
Input 1 Output
Input 2
Challenge #1: How can we compose these?

Here is another challenge
function AInput Output
function BInput
Output 1
Output 2
function AInput Output
function BInput
Output 1
Output 2
Challenge #2: How can we compose these?

COMPOSITION WITH BIND
(FIZZBUZZ)
Technique #3
FizzBuzz definition
• Write a program that prints the numbers
from 1 to 100
• But:
– For multiples of three print "Fizz" instead
– For multiples of five print "Buzz" instead
– For multiples of both three and five print
"FizzBuzz" instead.
let fizzBuzz max =
for n in [1..max] do
if (isDivisibleBy n 15) then
printfn "FizzBuzz"
else if (isDivisibleBy n 3) then
printfn "Fizz"
else if (isDivisibleBy n 5) then
printfn "Buzz"
else
printfn "%i" n
let isDivisibleBy n divisor =
(n % divisor) = 0 // helper function
A simple F# implementation
let fizzBuzz max =
for n in [1..max] do
if (isDivisibleBy n 15) then
printfn "FizzBuzz"
else if (isDivisibleBy n 3) then
printfn "Fizz"
else if (isDivisibleBy n 5) then
printfn "Buzz"
else
printfn "%i" n
let isDivisibleBy n divisor =
(n % divisor) = 0 // helper function
A simple F# implementation
Pipeline implementation
number Handle 15 case
Pipeline implementation
Handle 3 case
number Handle 15 case
Pipeline implementation
Handle 3 case
Handle 5 case
number Handle 15 case
Pipeline implementation
Handle 3 case
Handle 5 case
number
Answer
Handle 15 case
Last step
number Handle case
Carbonated
(e.g. "Fizz", "Buzz")
Uncarbonated
(e.g. 2, 7, 13)
Uncarbonated
Carbonated
Input ->
or
Uncarbonated
Carbonated
Input ->
type CarbonationResult =
| Uncarbonated of int // unprocessed
| Carbonated of string // "Fizz", Buzz", etc
Idea from http://weblog.raganwald.com/2007/01/dont-overthink-fizzbuzz.html
or
type CarbonationResult =
| Uncarbonated of int // unprocessed
| Carbonated of string // "Fizz", Buzz", etc
let carbonate divisor label n =
if (isDivisibleBy n divisor) then
Carbonated label
else
Uncarbonated n
Idea from http://weblog.raganwald.com/2007/01/dont-overthink-fizzbuzz.html
type CarbonationResult =
| Uncarbonated of int // unprocessed
| Carbonated of string // "Fizz", Buzz", etc
let carbonate divisor label n =
if (isDivisibleBy n divisor) then
Carbonated label
else
Uncarbonated n
12 |> carbonate 3 "Fizz" // Carbonated "Fizz"
10 |> carbonate 3 "Fizz" // Uncarbonated 10
10 |> carbonate 5 "Buzz" // Carbonated "Buzz"
carbonate 5 "Buzz"
let fizzbuzz n =
let result15 = n |> carbonate 15 "FizzBuzz"
match result15 with
| Carbonated str ->
str
| Uncarbonated n ->
let result3 = n |> carbonate 3 "Fizz"
match result3 with
| Carbonated str ->
str
| Uncarbonated n ->
let result5 = n |> carbonate 5 "Buzz"
match result5 with
| Carbonated str ->
str
| Uncarbonated n ->
string n // convert to string
First implementation attempt
let fizzbuzz n =
let result15 = n |> carbonate 15 "FizzBuzz"
match result15 with
| Carbonated str ->
str
| Uncarbonated n ->
let result3 = n |> carbonate 3 "Fizz"
match result3 with
| Carbonated str ->
str
| Uncarbonated n ->
let result5 = n |> carbonate 5 "Buzz"
match result5 with
| Carbonated str ->
str
| Uncarbonated n ->
// do something with Uncarbonated value
let fizzbuzz n =
let result15 = n |> carbonate 15 "FizzBuzz"
match result15 with
| Carbonated str ->
str
| Uncarbonated n ->
let result3 = n |> carbonate 3 "Fizz"
match result3 with
| Carbonated str ->
str
| Uncarbonated n ->
// do something with Uncarbonated value
// ...
// ...
let fizzbuzz n =
let result15 = n |> carbonate 15 "FizzBuzz"
match result15 with
| Carbonated str ->
str
| Uncarbonated n ->
// do something with Uncarbonated value
// ...
// ...
if Carbonated then
// return the string
if Uncarbonated then
// do something with the number
If Uncarbonated
If Carbonated
Bypass and
return the string
let ifUncarbonatedDo f result =
match result with
| Carbonated str ->
Carbonated str
| Uncarbonated n ->
f n
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> lastStep
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> lastStep
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> lastStep
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> lastStep
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> lastStep
let lastStep result =
match result with
| Carbonated str ->
str
| Uncarbonated n ->
string(n) // still not fizzy, so
// convert to string
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> lastStep
Composable => easy to extend
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> ifUncarbonatedDo (carbonate 7 "Baz")
|> lastStep
Composable => easy to extend
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> ifUncarbonatedDo (carbonate 7 "Baz")
|> ifUncarbonatedDo (carbonate 11 "Pozz")
|> lastStep
Composable => easy to extend
let fizzbuzz n =
n
|> carbonate 15 "FizzBuzz"
|> ifUncarbonatedDo (carbonate 3 "Fizz")
|> ifUncarbonatedDo (carbonate 5 "Buzz")
|> ifUncarbonatedDo (carbonate 7 "Baz")
|> ifUncarbonatedDo (carbonate 11 "Pozz")
|> ifUncarbonatedDo (carbonate 13 "Tazz")
|> lastStep
Composable => easy to extend
Another example:
Chaining tasks
When task
completesWait Wait
a.k.a "promise", "future"
let taskExample input =
let taskX = startTask input
taskX.WhenFinished (fun x ->
let taskY = startAnotherTask x
taskY.WhenFinished (fun y ->
let taskZ = startThirdTask y
taskZ.WhenFinished (fun z ->
etc
let taskExample input =
let taskX = startTask input
taskX.WhenFinished (fun x ->
let taskY = startAnotherTask x
taskY.WhenFinished (fun y ->
let taskZ = startThirdTask y
taskZ.WhenFinished (fun z ->
do something
let taskExample input =
let taskX = startTask input
taskX.WhenFinished (fun x ->
let taskY = startAnotherTask x
taskY.WhenFinished (fun y ->
do something
let taskExample input =
let taskX = startTask input
taskX.WhenFinished (fun x ->
do something
let whenFinishedDo f task =
task.WhenFinished (fun taskResult ->
f taskResult)
let taskExample input =
startTask input
|> whenFinishedDo startAnotherTask
|> whenFinishedDo startThirdTask
|> whenFinishedDo ...
Parameterize the next step
MONADS!
Is there a general solution to
handling functions like this?
Yes! “Bind” is the answer!
Bind all the things!
How do we compose these?
>> >>
Composing one-track functions is fine...
>> >>
... and composing two-track functions is fine...
 
... but composing points/switches is not allowed!
Two-track input Two-track output
One-track input Two-track output


Two-track input Two-track output
Two-track input Two-track output
A function transformer
let bind nextFunction result =
match result with
| Uncarbonated n ->
nextFunction n
| Carbonated str ->
Carbonated str
Two-track input Two-track output
let bind nextFunction result =
match result with
| Uncarbonated n ->
nextFunction n
| Carbonated str ->
Carbonated str
Two-track input Two-track output
let bind nextFunction result =
match result with
| Uncarbonated n ->
nextFunction n
| Carbonated str ->
Carbonated str
Two-track input Two-track output
let bind nextFunction result =
match result with
| Uncarbonated n ->
nextFunction n
| Carbonated str ->
Carbonated str
Two-track input Two-track output
let bind nextFunction result =
match result with
| Uncarbonated n ->
nextFunction n
| Carbonated str ->
Carbonated str
Two-track input Two-track output
FP terminology
• A monad is
– A data type
– With an associated "bind" function
– (and some other stuff)
• A monadic function is
– A switch/points function
– "bind" is used to compose them
type CarbonationResult =
| Uncarbonated of int
| Carbonated of string
function AInput Output
function BInput
Output 1
Output 2
Challenge #2: How can we compose these?

KLEISLI COMPOSITION
(WEB SERVICE)
Technique #4
=
compose
with
The result is the
same kind of thing
Kleisli Composition
Async<HttpContext option>HttpContext
A HttpHandler "WebPart"
Async<HttpContext option>HttpContext
A HttpHandler "WebPart"
=>=>
The result is another
HttpHandler so you can
keep adding and adding
Composition of HttpHandlers
Kleisli composition symbol
path "/hello"
Checks request path
(might fail)
matches path
doesn't match
OK "Hello"
Sets response
200 OK
path "/hello" >=> OK "Hello"
Checks request path
(might fail)
Sets response
>=>
A new WebPart
choose [
]
Picks first HttpHandler
that succeeds
choose [
path "/hello" >=> OK "Hello"
path "/goodbye" >=> OK "Goodbye"
]
Pick first path
that succeeds
GET
Only succeeds if
request is a GET
GET >=> choose [
path "/hello" >=> OK "Hello"
path "/goodbye" >=> OK "Goodbye"
]
let app = choose [
]
startWebServer defaultConfig app
A complete web app
GET >=> choose [
path "/hello" >=> OK "Hello"
path "/goodbye" >=> OK "Goodbye"
]
POST >=> choose [
path "/hello" >=> OK "Hello POST"
path "/goodbye" >=> OK "Goodbye POST"
]
Http
Response
Http
Request
No classes, no inheritance, one-directional data flow!
Review
• The philosophy of composition
– Connectable, reusable parts
• FP principles:
– Composable functions
– Composable types
Review
A taste of various composition techniques:
– Piping with "|>"
– Currying/partial application
– Composition using "bind" (monads!)
– Kleisli composition using ">=>"
Don't worry about understanding it all,
but hopefully it's not so scary now!
Why bother?
Benefits of composition:
• Reusable parts – no strings attached
• Testable – parts can be tested in isolation
• Understandable – data flows in one direction
• Maintainable – all dependencies are explicit
• Extendable – can add new parts without touching
old code
• A different way of thinking – it's good for
your brain to learn new things!
Slides and video here
fsharpforfunandprofit.com/composition
Thank you, DotNext!
@ScottWlaschin Me on twitter
My book Ask me anything
about railways!

More Related Content

What's hot

Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsScott Wlaschin
 
Thirteen ways of looking at a turtle
Thirteen ways of looking at a turtleThirteen ways of looking at a turtle
Thirteen ways of looking at a turtleScott Wlaschin
 
Developing and Deploying Apps with the Postgres FDW
Developing and Deploying Apps with the Postgres FDWDeveloping and Deploying Apps with the Postgres FDW
Developing and Deploying Apps with the Postgres FDWJonathan Katz
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of CompositionScott Wlaschin
 
Operator overloading
Operator overloadingOperator overloading
Operator overloadingBurhan Ahmed
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & StreamsEyal Vardi
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in SwiftSaugat Gautam
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsGuilherme Blanco
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...Philip Schwarz
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Philip Schwarz
 
The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)Scott Wlaschin
 
Python 테스트 시작하기
Python 테스트 시작하기Python 테스트 시작하기
Python 테스트 시작하기Hosung Lee
 
Let's discover React and Redux with TypeScript
Let's discover React and Redux with TypeScriptLet's discover React and Redux with TypeScript
Let's discover React and Redux with TypeScriptMathieu Savy
 

What's hot (20)

Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of tests
 
Thirteen ways of looking at a turtle
Thirteen ways of looking at a turtleThirteen ways of looking at a turtle
Thirteen ways of looking at a turtle
 
Ruby
RubyRuby
Ruby
 
Developing and Deploying Apps with the Postgres FDW
Developing and Deploying Apps with the Postgres FDWDeveloping and Deploying Apps with the Postgres FDW
Developing and Deploying Apps with the Postgres FDW
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of Composition
 
Operator overloading
Operator overloadingOperator overloading
Operator overloading
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & Streams
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in Swift
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object Calisthenics
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)
 
Python 테스트 시작하기
Python 테스트 시작하기Python 테스트 시작하기
Python 테스트 시작하기
 
Let's discover React and Redux with TypeScript
Let's discover React and Redux with TypeScriptLet's discover React and Redux with TypeScript
Let's discover React and Redux with TypeScript
 
LINQ
LINQLINQ
LINQ
 

Similar to The Power Of Composition (DotNext 2019)

Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Scott Wlaschin
 
DISE - Windows Based Application Development in C#
DISE - Windows Based Application Development in C#DISE - Windows Based Application Development in C#
DISE - Windows Based Application Development in C#Rasan Samarasinghe
 
F# and Reactive Programming for iOS
F# and Reactive Programming for iOSF# and Reactive Programming for iOS
F# and Reactive Programming for iOSBrad Pillow
 
DITEC - Programming with C#.NET
DITEC - Programming with C#.NETDITEC - Programming with C#.NET
DITEC - Programming with C#.NETRasan Samarasinghe
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScriptGarth Gilmour
 
Think sharp, write swift
Think sharp, write swiftThink sharp, write swift
Think sharp, write swiftPascal Batty
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Scott Wlaschin
 
Functional pogramming hl overview
Functional pogramming hl overviewFunctional pogramming hl overview
Functional pogramming hl overviewElad Avneri
 
Programming with python
Programming with pythonProgramming with python
Programming with pythonsarogarage
 
The top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebasesThe top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebasesPhil Nash
 
Introduction to C++
Introduction to C++ Introduction to C++
Introduction to C++ Bharat Kalia
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987乐群 陈
 
Антон Молдован "Type driven development with f#"
Антон Молдован "Type driven development with f#"Антон Молдован "Type driven development with f#"
Антон Молдован "Type driven development with f#"Fwdays
 
Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a MomentSergio Gil
 
Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...
Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...
Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...Aslak Hellesøy
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 

Similar to The Power Of Composition (DotNext 2019) (20)

Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)
 
Python slide
Python slidePython slide
Python slide
 
Cucumber
CucumberCucumber
Cucumber
 
DISE - Windows Based Application Development in C#
DISE - Windows Based Application Development in C#DISE - Windows Based Application Development in C#
DISE - Windows Based Application Development in C#
 
F# and Reactive Programming for iOS
F# and Reactive Programming for iOSF# and Reactive Programming for iOS
F# and Reactive Programming for iOS
 
DITEC - Programming with C#.NET
DITEC - Programming with C#.NETDITEC - Programming with C#.NET
DITEC - Programming with C#.NET
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
Think sharp, write swift
Think sharp, write swiftThink sharp, write swift
Think sharp, write swift
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
Functional pogramming hl overview
Functional pogramming hl overviewFunctional pogramming hl overview
Functional pogramming hl overview
 
Programming with python
Programming with pythonProgramming with python
Programming with python
 
The top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebasesThe top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebases
 
Introduction to C++
Introduction to C++ Introduction to C++
Introduction to C++
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 
Антон Молдован "Type driven development with f#"
Антон Молдован "Type driven development with f#"Антон Молдован "Type driven development with f#"
Антон Молдован "Type driven development with f#"
 
Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a Moment
 
Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...
Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...
Executable Requirements with Behaviour-Driven Development and Cucumber - Euro...
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 

More from Scott Wlaschin

Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Scott Wlaschin
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Scott Wlaschin
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Scott Wlaschin
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Scott Wlaschin
 
Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)Scott Wlaschin
 
Four Languages From Forty Years Ago
Four Languages From Forty Years AgoFour Languages From Forty Years Ago
Four Languages From Forty Years AgoScott Wlaschin
 
Designing with capabilities (DDD-EU 2017)
Designing with capabilities (DDD-EU 2017)Designing with capabilities (DDD-EU 2017)
Designing with capabilities (DDD-EU 2017)Scott Wlaschin
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with CapabilitiesScott Wlaschin
 
An introduction to property based testing
An introduction to property based testingAn introduction to property based testing
An introduction to property based testingScott Wlaschin
 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Scott Wlaschin
 

More from Scott Wlaschin (14)

Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)
 
Four Languages From Forty Years Ago
Four Languages From Forty Years AgoFour Languages From Forty Years Ago
Four Languages From Forty Years Ago
 
F# for C# Programmers
F# for C# ProgrammersF# for C# Programmers
F# for C# Programmers
 
Designing with capabilities (DDD-EU 2017)
Designing with capabilities (DDD-EU 2017)Designing with capabilities (DDD-EU 2017)
Designing with capabilities (DDD-EU 2017)
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with Capabilities
 
An introduction to property based testing
An introduction to property based testingAn introduction to property based testing
An introduction to property based testing
 
Swift vs. Language X
Swift vs. Language XSwift vs. Language X
Swift vs. Language X
 
Doge-driven design
Doge-driven designDoge-driven design
Doge-driven design
 
The Theory of Chains
The Theory of ChainsThe Theory of Chains
The Theory of Chains
 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013
 

Recently uploaded

XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningVitsRangannavar
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 

Recently uploaded (20)

XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learning
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 

The Power Of Composition (DotNext 2019)

  • 1. DotNext 2019 The Power Of Composition @ScottWlaschin fsharpforfunandprofit.com
  • 2. The Power Of Composition 1. The philosophy of composition 2. Ideas of functional programming – Functions and how to compose them – Types and how to compose them 3. Composition in practice – Roman Numerals – FizzBuzz gone carbonated – Uh oh, monads! – A web service
  • 4. Prerequisites for understanding composition • You must have been a child at some point • You must have played with Lego • You must have played with toy trains
  • 6. Lego Philosophy 1. All pieces are designed to be connected 2. The pieces are reusable in many contexts 3. Connect two pieces together and get another "piece" that can still be connected
  • 7. All pieces are designed to be connected
  • 8. The pieces are reusable in different contexts
  • 9. Connect two pieces together and get another "piece" that can still be connected
  • 10. Make big things from small things in the same way
  • 11.
  • 12. Wooden Railway Track Philosophy 1. All pieces are designed to be connected 2. The pieces are reusable in many contexts 3. Connect two pieces together and get another "piece" that can still be connected
  • 13. All pieces are designed to be connected
  • 14. The pieces are reusable in different contexts
  • 15. Connect two pieces together and get another "piece" that can still be connected You can keep adding and adding.
  • 16. Make big things from small things in the same way
  • 17. If you understand Lego and wooden railways, then you know everything about composition!
  • 18. THE IDEAS OF FUNCTIONAL PROGRAMMING
  • 19. Four ideas behind FP Function 3.Types are not classes 1. Functions are things 2. Build bigger functions using composition 4. Build bigger types using composition
  • 20. FP idea #1: Functions are things Function
  • 21. The Tunnel of Transformation Function apple -> banana A function is a thing which transforms inputs to outputs
  • 22. A function is a standalone thing, not attached to a class
  • 23. A function is a standalone thing, not attached to a class It can be used for inputs and outputs of other functions
  • 24. A function can be an output thing input
  • 25. output A function can be an input thing
  • 26. input output A function can be a parameter
  • 28. FP idea #2: Build bigger functions using composition
  • 29. Function 1 apple -> banana Function 2 banana -> cherry
  • 30. >> Function 1 apple -> banana Function 2 banana -> cherry
  • 31. New Function apple -> cherry Can't tell it was built from smaller functions! Where did the banana go?
  • 32. Function composition in F# and C# using the "piping" approach
  • 33. int add1(int x) => x + 1; int times2(int x) => x * 2; int square(int x) => x * x; add1(5); // = 6 times2(add1(5)); // = 12 square(times2(add1(5))); // = 144 Nested function calls can be confusing if too deep
  • 34. add15 6 times2 12 square 144
  • 35. 5 |> add1 // = 6 5 |> add1 |> times2 // = 12 5 |> add1 |> times2 |> square // = 144 add1 times2 square5 6 12 144 F# example
  • 36. add1 times2 square5 6 12 144 5.Pipe(add1); 5.Pipe(add1).Pipe(times2); 5.Pipe(add1).Pipe(times2).Pipe(square); C# example
  • 37. Building big things from functions It's compositions all the way up
  • 39. Low-level operation Service AddressValidator A “Service” is just like a microservice but without the "micro" in front Validation Result Address Low-level operation Low-level operation
  • 42. Http Response Http Request Even for complex applications, data flows only in one direction
  • 43.
  • 44.
  • 45. FP idea #3: Types are not classes
  • 46. So, what is a type then? A type is a just a name for a set of things Set of valid inputs Set of valid outputs Function
  • 47. Set of valid inputs Set of valid outputs Function 1 2 3 4 5 6 This is type "integer" A type is a just a name for a set of things
  • 48. Set of valid inputs Set of valid outputs Function This is type "string" "abc" "but" "cobol" "double" "end" "float" A type is a just a name for a set of things
  • 49. Set of valid inputs Set of valid outputs Function This is type "Person" Donna Roy Javier Mendoza Nathan Logan Shawna Ingram Abel Ortiz Lena Robbins GordonWood A type is a just a name for a set of things
  • 50. Set of valid inputs Set of valid outputs Function This is type "Fruit" A type is a just a name for a set of things
  • 51. Set of valid inputs Set of valid outputs Function This is a type of Fruit->Fruit functions A type is a just a name for a set of things
  • 52. FP idea #4: Types can be composed too
  • 54. Bigger types are built from smaller types by: Composing with “AND” Composing with “OR”
  • 56. Compose with “AND” enum AppleVariety { Red, Green } enum BananaVariety { Yellow, Brown } enum CherryVariety { Tart, Sweet } struct FruitSalad { AppleVariety Apple; BananaVariety Banana; CherryVariety Cherry; } C# example Apple AND Banana AND Cherry
  • 57. Compose with “AND” type AppleVariety = Red | Green type BananaVariety = Yellow | Brown type CherryVariety = Tart | Sweet type FruitSalad = { Apple: AppleVariety Banana: BananaVariety Cherry: CherryVariety } F# example
  • 58. Snack = OR OR Compose with “OR” type Snack = | Apple of AppleVariety | Banana of BananaVariety | Cherry of CherryVariety
  • 59. A real world example of composing types
  • 60. Some requirements: We accept three forms of payment: Cash, Paypal, or CreditCard. For Cash we don't need any extra information For Paypal we need an email address For Cards we need a card type and card number
  • 61. interface IPaymentMethod {..} class Cash() : IPaymentMethod {..} class Paypal(string emailAddress): IPaymentMethod {..} class Card(string cardType, string cardNo) : IPaymentMethod {..} In OO design you would probably implement it as an interface and a set of subclasses, like this:
  • 62. type EmailAddress = string type CardNumber = string In F# you would probably implement by composing types, like this:
  • 63. type EmailAddress = ... type CardNumber = … type CardType = Visa | Mastercard type CreditCardInfo = { CardType : CardType CardNumber : CardNumber }
  • 64. type EmailAddress = ... type CardNumber = ... type CardType = ... type CreditCardInfo = ... type PaymentMethod = | Cash | PayPal of EmailAddress | Card of CreditCardInfo
  • 65. type EmailAddress = ... type CardNumber = ... type CardType = ... type CreditCardInfo = ... type PaymentMethod = | Cash | PayPal of EmailAddress | Card of CreditCardInfo type PaymentAmount = decimal type Currency = EUR | USD | RUB
  • 66. type EmailAddress = ... type CardNumber = ... type CardType = ... type CreditCardInfo = ... type PaymentMethod = | Cash | PayPal of EmailAddress | Card of CreditCardInfo type PaymentAmount = decimal type Currency = EUR | USD | RUB type Payment = { Amount : PaymentAmount Currency : Currency Method : PaymentMethod }
  • 67. type EmailAddress = ... type CardNumber = ... type CardType = ... type CreditCardInfo = ... type PaymentMethod = | Cash | PayPal of EmailAddress | Card of CreditCardInfo type PaymentAmount = decimal type Currency = EUR | USD | RUB type Payment = { Amount : PaymentAmount Currency : Currency Method : PaymentMethod }
  • 68.
  • 69. Composable types can be used as executable documentation
  • 70. type Deal = Deck -> (Deck * Card) type PickupCard = (Hand * Card) -> Hand type Suit = Club | Diamond | Spade | Heart type Rank = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | Ace type Card = { Suit:Suit; Rank:Rank } type Hand = Card list type Deck = Card list type Player = {Name:string; Hand:Hand} type Game = { Deck:Deck; Players:Player list } The domain on one screen!
  • 71. type CardType = Visa | Mastercard type CardNumber = string type EmailAddress = string type PaymentMethod = | Cash | PayPal of EmailAddress | Card of CreditCardInfo | Bitcoin of BitcoinAddress
  • 72. A big topic and not enough time   More on DDD and designing with types at fsharpforfunandprofit.com/ddd
  • 73. Composition in practice: Time for some real examples!
  • 74. COMPOSITION WITH PIPING (ROMAN NUMERALS) Technique #1
  • 75. To Roman Numerals • Task: How to convert an arabic integer to roman numerals? • 5 => "V" • 12 => "XII" • 107 => "CVII"
  • 77. To Roman Numerals • Use the "tally" approach – Start with N copies of "I" – Replace five "I"s with a "V" – Replace two "V"s with a "X" – Replace five "X"s with a "L" – Replace two "L"s with a "C" – etc
  • 78. To Roman Numerals number etc Replicate "I" Replace_IIIII_V Replace_VV_X Replace_XXXXX_L
  • 79. string ToRomanNumerals(int number) { // define a helper function for each step string replace_IIIII_V(string s) => s.Replace("IIIII", "V"); string replace_VV_X(string s) => s.Replace("VV", "X"); string replace_XXXXX_L(string s) => s.Replace("XXXXX", "L"); string replace_LL_C(string s) => s.Replace("LL", "C"); // then combine them using piping return new string('I', number) .Pipe(replace_IIIII_V) .Pipe(replace_VV_X) .Pipe(replace_XXXXX_L) .Pipe(replace_LL_C); } C# example
  • 80. let toRomanNumerals number = // define a helper function for each step let replace_IIIII_V str = replace "IIIII" "V" str let replace_VV_X str = replace "VV" "X" str let replace_XXXXX_L str = replace "XXXXX" "L" str let replace_LL_C str = replace "LL" "C" str // then combine them using piping String.replicate number "I" |> replace_IIIII_V |> replace_VV_X |> replace_XXXXX_L |> replace_LL_C F# example
  • 84. function A and B Easy!
  • 85. ... But here is a challenge
  • 86. function AInput Output function B Input 1 Output Input 2
  • 87. function AInput Output function B Input 1 Output Input 2 Challenge #1: How can we compose these? 
  • 89. The Replace function oldValue outputString newValue inputString Replace
  • 90. Uh-oh! Composition problem Replace I / V Replace V / X Replace X / L 
  • 91. Bad news: Composition patterns only work for functions that have one parameter! 
  • 92. Good news! Every function can be turned into a one parameter function 
  • 93. Haskell Curry We named this technique after him
  • 94. Input A Uncurried Function Input B Output C Curried Function Input A Intermediate Function Output CInput B What is currying? after currying Function as output
  • 95. Input A Uncurried Function Input B Output C Curried Function Input A Intermediate Function Output CInput B What is currying? One input One input Currying means that *every* function can be converted to a series of one input functions
  • 97. Replace Old New Old New After currying Func<string,string> replace(string oldVal, string newVal) => input => input.Replace(oldVal, newVal);
  • 98. Replace Old New Old New After currying Func<string,string> replace(string oldVal, string newVal) => input => input.Replace(oldVal, newVal);
  • 99. Func<string,string> replace(string oldVal, string newVal) => input => input.Replace(oldVal, newVal); Replace Old New Old New After currying This lambda (function) is returned one-parameter function
  • 100. string ToRomanNumerals(int number) { // define a general helper function Func<string,string> replace( string oldValue, string newValue) => input => input.Replace(oldValue, newValue); // then use piping return new string('I', number) .Pipe(replace("IIIII","V")) .Pipe(replace("VV","X")) .Pipe(replace("XXXXX","L")) .Pipe(replace("LL","C")); } C# example
  • 101. let toRomanNumerals number = // no helper function needed. // currying occurs automatically in F# // combine using piping String.replicate number "I" |> replace "IIIII" "V" |> replace "VV" "X" |> replace "XXXXX" "L" |> replace "LL" "C" F# example
  • 102. let toRomanNumerals number = // no helper function needed. // currying occurs automatically in F# // combine using piping String.replicate number "I" |> replace "IIIII" "V" |> replace "VV" "X" |> replace "XXXXX" "L" |> replace "LL" "C" Only 2 of the 3 parameters are passed ?
  • 104. Partial Application let add x y = x + y let multiply x y = x * y 5 |> add 2 |> multiply 3 Piping provides the missing argument partial application
  • 105. Partial Application Replace ReplaceOldNew Old New Old New String.replicate number "I" |> replace "IIIII" "V" |> replace "VV" "X" |> replace "XXXXX" "L" |> replace "LL" "C" Only 2 parameters passed in Piping provides the missing argument
  • 107. let toRomanNumerals number = String.replicate number "I" |> replace "IIIII" "V" |> replace "VV" "X" |> replace "XXXXX" "L" |> replace "LL" "C" Composable => extensible // can easily add new segments to the pipeline |> replace "VIIII" "IX" |> replace "IIII" "IV" |> replace "LXXXX" "XC"
  • 108. functionInput Output function Input 1 Output Input 2 Challenge #1: How can we compose these? 
  • 109. Here is another challenge
  • 110. function AInput Output function BInput Output 1 Output 2
  • 111. function AInput Output function BInput Output 1 Output 2 Challenge #2: How can we compose these? 
  • 113. FizzBuzz definition • Write a program that prints the numbers from 1 to 100 • But: – For multiples of three print "Fizz" instead – For multiples of five print "Buzz" instead – For multiples of both three and five print "FizzBuzz" instead.
  • 114. let fizzBuzz max = for n in [1..max] do if (isDivisibleBy n 15) then printfn "FizzBuzz" else if (isDivisibleBy n 3) then printfn "Fizz" else if (isDivisibleBy n 5) then printfn "Buzz" else printfn "%i" n let isDivisibleBy n divisor = (n % divisor) = 0 // helper function A simple F# implementation
  • 115. let fizzBuzz max = for n in [1..max] do if (isDivisibleBy n 15) then printfn "FizzBuzz" else if (isDivisibleBy n 3) then printfn "Fizz" else if (isDivisibleBy n 5) then printfn "Buzz" else printfn "%i" n let isDivisibleBy n divisor = (n % divisor) = 0 // helper function A simple F# implementation
  • 117. Pipeline implementation Handle 3 case number Handle 15 case
  • 118. Pipeline implementation Handle 3 case Handle 5 case number Handle 15 case
  • 119. Pipeline implementation Handle 3 case Handle 5 case number Answer Handle 15 case Last step
  • 120. number Handle case Carbonated (e.g. "Fizz", "Buzz") Uncarbonated (e.g. 2, 7, 13)
  • 122. Uncarbonated Carbonated Input -> type CarbonationResult = | Uncarbonated of int // unprocessed | Carbonated of string // "Fizz", Buzz", etc Idea from http://weblog.raganwald.com/2007/01/dont-overthink-fizzbuzz.html or
  • 123. type CarbonationResult = | Uncarbonated of int // unprocessed | Carbonated of string // "Fizz", Buzz", etc let carbonate divisor label n = if (isDivisibleBy n divisor) then Carbonated label else Uncarbonated n Idea from http://weblog.raganwald.com/2007/01/dont-overthink-fizzbuzz.html
  • 124. type CarbonationResult = | Uncarbonated of int // unprocessed | Carbonated of string // "Fizz", Buzz", etc let carbonate divisor label n = if (isDivisibleBy n divisor) then Carbonated label else Uncarbonated n
  • 125. 12 |> carbonate 3 "Fizz" // Carbonated "Fizz" 10 |> carbonate 3 "Fizz" // Uncarbonated 10 10 |> carbonate 5 "Buzz" // Carbonated "Buzz" carbonate 5 "Buzz"
  • 126. let fizzbuzz n = let result15 = n |> carbonate 15 "FizzBuzz" match result15 with | Carbonated str -> str | Uncarbonated n -> let result3 = n |> carbonate 3 "Fizz" match result3 with | Carbonated str -> str | Uncarbonated n -> let result5 = n |> carbonate 5 "Buzz" match result5 with | Carbonated str -> str | Uncarbonated n -> string n // convert to string First implementation attempt
  • 127. let fizzbuzz n = let result15 = n |> carbonate 15 "FizzBuzz" match result15 with | Carbonated str -> str | Uncarbonated n -> let result3 = n |> carbonate 3 "Fizz" match result3 with | Carbonated str -> str | Uncarbonated n -> let result5 = n |> carbonate 5 "Buzz" match result5 with | Carbonated str -> str | Uncarbonated n -> // do something with Uncarbonated value
  • 128. let fizzbuzz n = let result15 = n |> carbonate 15 "FizzBuzz" match result15 with | Carbonated str -> str | Uncarbonated n -> let result3 = n |> carbonate 3 "Fizz" match result3 with | Carbonated str -> str | Uncarbonated n -> // do something with Uncarbonated value // ... // ...
  • 129. let fizzbuzz n = let result15 = n |> carbonate 15 "FizzBuzz" match result15 with | Carbonated str -> str | Uncarbonated n -> // do something with Uncarbonated value // ... // ...
  • 130. if Carbonated then // return the string if Uncarbonated then // do something with the number
  • 131. If Uncarbonated If Carbonated Bypass and return the string
  • 132. let ifUncarbonatedDo f result = match result with | Carbonated str -> Carbonated str | Uncarbonated n -> f n
  • 133. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> lastStep
  • 134. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> lastStep
  • 135. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> lastStep
  • 136. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> lastStep
  • 137. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> lastStep let lastStep result = match result with | Carbonated str -> str | Uncarbonated n -> string(n) // still not fizzy, so // convert to string
  • 138. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> lastStep Composable => easy to extend
  • 139. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> ifUncarbonatedDo (carbonate 7 "Baz") |> lastStep Composable => easy to extend
  • 140. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> ifUncarbonatedDo (carbonate 7 "Baz") |> ifUncarbonatedDo (carbonate 11 "Pozz") |> lastStep Composable => easy to extend
  • 141. let fizzbuzz n = n |> carbonate 15 "FizzBuzz" |> ifUncarbonatedDo (carbonate 3 "Fizz") |> ifUncarbonatedDo (carbonate 5 "Buzz") |> ifUncarbonatedDo (carbonate 7 "Baz") |> ifUncarbonatedDo (carbonate 11 "Pozz") |> ifUncarbonatedDo (carbonate 13 "Tazz") |> lastStep Composable => easy to extend
  • 143. When task completesWait Wait a.k.a "promise", "future"
  • 144. let taskExample input = let taskX = startTask input taskX.WhenFinished (fun x -> let taskY = startAnotherTask x taskY.WhenFinished (fun y -> let taskZ = startThirdTask y taskZ.WhenFinished (fun z -> etc
  • 145. let taskExample input = let taskX = startTask input taskX.WhenFinished (fun x -> let taskY = startAnotherTask x taskY.WhenFinished (fun y -> let taskZ = startThirdTask y taskZ.WhenFinished (fun z -> do something
  • 146. let taskExample input = let taskX = startTask input taskX.WhenFinished (fun x -> let taskY = startAnotherTask x taskY.WhenFinished (fun y -> do something
  • 147. let taskExample input = let taskX = startTask input taskX.WhenFinished (fun x -> do something
  • 148. let whenFinishedDo f task = task.WhenFinished (fun taskResult -> f taskResult) let taskExample input = startTask input |> whenFinishedDo startAnotherTask |> whenFinishedDo startThirdTask |> whenFinishedDo ... Parameterize the next step
  • 150. Is there a general solution to handling functions like this?
  • 151. Yes! “Bind” is the answer! Bind all the things!
  • 152. How do we compose these?
  • 153.
  • 154. >> >> Composing one-track functions is fine...
  • 155. >> >> ... and composing two-track functions is fine...
  • 156.   ... but composing points/switches is not allowed!
  • 157. Two-track input Two-track output One-track input Two-track output  
  • 159. Two-track input Two-track output A function transformer
  • 160. let bind nextFunction result = match result with | Uncarbonated n -> nextFunction n | Carbonated str -> Carbonated str Two-track input Two-track output
  • 161. let bind nextFunction result = match result with | Uncarbonated n -> nextFunction n | Carbonated str -> Carbonated str Two-track input Two-track output
  • 162. let bind nextFunction result = match result with | Uncarbonated n -> nextFunction n | Carbonated str -> Carbonated str Two-track input Two-track output
  • 163. let bind nextFunction result = match result with | Uncarbonated n -> nextFunction n | Carbonated str -> Carbonated str Two-track input Two-track output
  • 164. let bind nextFunction result = match result with | Uncarbonated n -> nextFunction n | Carbonated str -> Carbonated str Two-track input Two-track output
  • 165. FP terminology • A monad is – A data type – With an associated "bind" function – (and some other stuff) • A monadic function is – A switch/points function – "bind" is used to compose them type CarbonationResult = | Uncarbonated of int | Carbonated of string
  • 166. function AInput Output function BInput Output 1 Output 2 Challenge #2: How can we compose these? 
  • 168. = compose with The result is the same kind of thing Kleisli Composition
  • 171. =>=> The result is another HttpHandler so you can keep adding and adding Composition of HttpHandlers Kleisli composition symbol
  • 172. path "/hello" Checks request path (might fail) matches path doesn't match
  • 174. path "/hello" >=> OK "Hello" Checks request path (might fail) Sets response >=> A new WebPart
  • 175. choose [ ] Picks first HttpHandler that succeeds
  • 176. choose [ path "/hello" >=> OK "Hello" path "/goodbye" >=> OK "Goodbye" ] Pick first path that succeeds
  • 178. GET >=> choose [ path "/hello" >=> OK "Hello" path "/goodbye" >=> OK "Goodbye" ]
  • 179. let app = choose [ ] startWebServer defaultConfig app A complete web app GET >=> choose [ path "/hello" >=> OK "Hello" path "/goodbye" >=> OK "Goodbye" ] POST >=> choose [ path "/hello" >=> OK "Hello POST" path "/goodbye" >=> OK "Goodbye POST" ]
  • 180. Http Response Http Request No classes, no inheritance, one-directional data flow!
  • 181. Review • The philosophy of composition – Connectable, reusable parts • FP principles: – Composable functions – Composable types
  • 182. Review A taste of various composition techniques: – Piping with "|>" – Currying/partial application – Composition using "bind" (monads!) – Kleisli composition using ">=>" Don't worry about understanding it all, but hopefully it's not so scary now!
  • 183. Why bother? Benefits of composition: • Reusable parts – no strings attached • Testable – parts can be tested in isolation • Understandable – data flows in one direction • Maintainable – all dependencies are explicit • Extendable – can add new parts without touching old code • A different way of thinking – it's good for your brain to learn new things!
  • 184. Slides and video here fsharpforfunandprofit.com/composition Thank you, DotNext! @ScottWlaschin Me on twitter My book Ask me anything about railways!