SlideShare a Scribd company logo
1 of 117
Download to read offline
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
} // true if ownership of
// email address is confirmed
Domain Driven Design with the F# type system
Prologue: how many things are wrong?
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Prologue: which values are optional?
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Prologue: what are the constraints?
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Prologue: what groups are atomic?
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Prologue: domain logic?
Prologue: F# can help
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Domain Driven Design
with the F# type system
ScottWlaschin
@ScottWlaschin
fsharpforfunandprofit.com
FPbridge.co.uk
/ddd
What is DDD?
Functional
Programming
Domain
Modelling
What I’m going talk about:
• Demystifying functional programming
• Functional programming for real
world applications
• F# vs. C# for domain driven design
• Understanding the F# type system
• Designing with types
Demystifying functional
programming
Why is it so hard?
Functional programming is scary
Functional programming is scary
Object oriented programming is scary
Functional programming is scary
Functional programming
for real world applications
Functional programming is...
... good for mathematical and scientific tasks
... good for complicated algorithms
... really good for parallel processing
... but you need a PhD in computer science 
Functional programming is good for...
Boring
Line Of Business
Applications
(BLOBAs)
Must haves for BLOBA development...
• Express requirements clearly
• Rapid development cycle
• High quality deliverables
• Fun
F# vs. C#
for Domain Driven Design
A simple immutable object
How do you implement a Value object?
Equality based on comparing all properties
PersonalName:
FirstName = "Alice"
LastName = "Adams"
PersonalName:
FirstName = "Alice"
LastName = "Adams"Equal
Therefore must be immutable
class PersonalName
{
public PersonalName(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
}
Value object definition in C#
class PersonalName
{
public PersonalName(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
}
Value object definition in C#
class PersonalName
{
// all the code from above, plus...
public override int GetHashCode()
{
return this.FirstName.GetHashCode() + this.LastName.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as PersonalName);
}
public bool Equals(PersonalName other)
{
if ((object) other == null)
{
return false;
}
return FirstName == other.FirstName && LastName == other.LastName;
}
Value object definition in C# (extra code for equality)
type PersonalName = {FirstName:string; LastName:string}
Value object definition in F#
This page intentionally left blank
Value object definition in F# (extra code for equality)
How do you implement an Entity object?
Equality based on some sort of id
Person:
Id = 1
Name = "Alice Adams"
Person:
Id = 1
Name = "Bilbo Baggins"
Equal
X
 Generally has mutable content
class Person
{
public Person(int id, PersonalName name)
{
this.Id = id;
this.Name = name;
}
public int Id { get; private set; }
public PersonalName Name { get; set; }
}
Entity object definition in C# (part 1)
class Person
{
// all the code from above, plus...
public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as Person);
}
public bool Equals(Person other)
{
if ((object) other == null)
{
return false;
}
return Id == other.Id;
}
}
Entity object definition in C# (part 2)
[<CustomEquality; NoComparison>]
type Person = {Id:int; Name:PersonalName} with
override this.GetHashCode() = hash this.Id
override this.Equals(other) =
match other with
| :? Person as p -> (this.Id = p.Id)
| _ -> false
Entity object definition in F# with equality override
Entity object definition in F# with no equality allowed
[<CustomEquality; NoComparison>]
type Person = {Id:int; Name:PersonalName}
[<NoEquality; NoComparison>]
type Person = { ... ... ... }
let tryCreatePerson name =
// validate on construction
// if input is valid return something
// if input is not valid return error 

Advantages of immutability
class PersonalName
{
public PersonalName(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
public override int GetHashCode()
{
return this.FirstName.GetHashCode() +
this.LastName.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as PersonalName);
}
public bool Equals(PersonalName other)
{
if ((object) other == null)
{
return false;
}
return FirstName == other.FirstName &&
LastName == other.LastName;
}
}
Reviewing the C# code so far...
class Person
{
public Person(int id, PersonalName name)
{
this.Id = id;
this.Name = name;
}
public int Id { get; private set; }
public PersonalName Name { get; set; }
public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as Person);
}
public bool Equals(Person other)
{
if ((object) other == null)
{
return false;
}
return Id == other.Id;
}
}
: IValue : IEntity
[<StructuralEquality;NoComparison>]
type PersonalName = {
FirstName : string;
LastName : string }
Reviewing the F# code so far...
[<NoEquality; NoComparison>]
type Person = {
Id : int;
Name : PersonalName }
Comparing C# vs. F#
C# F#
Value objects? Non-trivial Easy
Entity objects? Non-trivial Easy
Value objects by default? No Yes
Immutable objects by default? No Yes
Can you tellValue objects
from Entities at a glance?
No Yes
Understandable by
non-programmer?
No Yes
C# vs. F# for DDD
F# for Domain Driven Design
Communicating a domain model
Communication is hard...
U-N-I-O-N-I-Z-EU-N-I-O-N-I-Z-EU-N-I-O-N-I-Z-E
Communication in DDD: “Bounded Context”
Business Chemistry
un-ionizeunionize
Supermarket Email System
SpamSpam
Communication in DDD: “Bounded Context”
Business Chemistry
un-ionizeunionize
Supermarket Email System
SpamSpam
Sales Warehouse
ProductProduct
Communication in DDD: “Bounded Context”
Business Chemistry
un-ionizeunionize
Supermarket Email System
SpamSpam
Sales Warehouse
ProductProduct
Marketing Finance
CustomerCustomer
Communication in DDD: “Ubiquitous Language”
Chemistry
Ion Atom Molecule Polymer Compound Bond
Communication in DDD: “Ubiquitous Language”
Chemistry
Ion Atom Molecule Polymer Compound Bond
Sales
Product Promotion Customer Tracking
Communication in DDD: “Ubiquitous Language”
Chemistry
Ion Atom Molecule Polymer Compound Bond
Sales
Product Promotion Customer Tracking
Warehouse
Product Stock Transfer Depot Tracking
module CardGame =
type Suit = Club | Diamond | Spade | Heart
type Rank = Two |Three | Four | Five | Six | Seven | Eight
| Nine |Ten | Jack | Queen | King | Ace
type Card = Suit * Rank
type Hand = Card list
type Deck = Card list
type Player = {Name:string; Hand:Hand}
type Game = {Deck:Deck; Players: Player list}
type Deal = Deck –› (Deck * Card)
type PickupCard = (Hand * Card) –› Hand
'*' means a pair. Choose one from each type
Ubiquitouslanguage
list type is built in
module CardGame =
type Suit = Club | Diamond | Spade | Heart
type Rank = Two |Three | Four | Five | Six | Seven | Eight
| Nine |Ten | Jack | Queen | King | Ace
type Card = Suit * Rank
type Hand = Card list
type Deck = Card list
type Player = {Name:string; Hand:Hand}
type Game = {Deck:Deck; Players: Player list}
type Deal = Deck –› (Deck * Card)
type PickupCard = (Hand * Card) –› Hand
module CardGame =
type Suit = Club | Diamond | Spade | Heart
type Rank = Two |Three | Four | Five | Six | Seven | Eight
| Nine |Ten | Jack | Queen | King | Ace
type Card = Suit * Rank
type Hand = Card list
type Deck = Card list
type Player = {Name:string; Hand:Hand}
type Game = {Deck:Deck; Players: Player list}
type Deal = Deck –› (Deck * Card)
type PickupCard = (Hand * Card) –› Hand
Understanding the F# type system
An introduction to “algebraic” typesAn introduction to “algebraic” types
Composable types
Creating new types
New types are constructed by combining other
types using two basic operations:
type typeW = typeX "times" typeY
type typeZ = typeX "plus" typeY
Creating new types
(a function)AddOneAddOne
int –› int
1
2
3
4
2
3
4
5
Representing pairs
AddPair
? –› int
(1,2)
(2,3)
(3,4)
(4,5)
3
5
7
9
Representing pairs
×=
(1,2)
(2,3)
(3,4)
(4,5)
1
2
3
4
2
3
4
5
Representing pairs
×=
(true, false)
(true, true)
(false, false)
(false, true)
true
false
true
false
Representing pairs
pair of ints
written int * int
pair of bools
written bool * bool
Using tuples for data
×=
Alice, Jan 12th
Bob, Feb 2nd
Carol, Mar 3rd
Set of
people
Set of
dates
Using tuples for data
×=
Alice, Jan 12th
Bob, Feb 2nd
Carol, Mar 3rd
Set of
people
Set of
dates
type Birthday = Person * Date
Representing a choice
Temp F
IsFever
? –› bool
true
false
Temp C
or
Representing a choice
+=
98˚ F
99˚ F
100˚ F
101˚ F
37.0˚ C
37.5˚ C
38.0˚ C
38.5˚ C
Temp F
Temp C
or
Representing a choice
+=
98˚ F
99˚ F
100˚ F
101˚ F
37.0˚ C
37.5˚ C
38.0˚ C
38.5˚ C
Temp F
Temp C
or
Tag these with “C”
typeTemp =
| F of int
| C of float
Using choices for data
type PaymentMethod =
| Cash
| Cheque of int
| Card of CardType * CardNumber
Working with a choice type
type PaymentMethod =
| Cash
| Cheque of int
| Card of CardType * CardNumber
let printPayment method =
match method with
| Cash –›
printfn “Paid in cash"
| Cheque checkNo –›
printfn “Paid by cheque: %i" checkNo
| Card (cardType,cardNo) –›
printfn “Paid with %A %A" cardType cardNo
Using choices vs. inheritance
interface IPaymentMethod {..}
class Cash : IPaymentMethod {..}
class Cheque : IPaymentMethod {..}
class Card : IPaymentMethod {..}
type PaymentMethod =
| Cash
| Cheque of int
| Card of CardType * CardNumber
class Evil : IPaymentMethod {..}
Data and code is scattered
around many locations
What goes in here? What
is the common behaviour?
OO version:
Summary: What are types for in FP?
An annotation to a value for type checking
type AddOne: int –› int
Domain modelling tool
type Deal = Deck –› (Deck * Card)
TYPE ALL THE THINGS
Designing with types
What can we do with this type system?
Required vs. Optional
type PersonalName =
{
FirstName: string;
MiddleInitial: string;
LastName: string;
}
required
required
optional
Null is not the same as “optional”
Length
string –› int
“a”
“b”
“c”
1
2
3
“a”
“b”
“c”
null
Spock, set
phasers to null!
That is illogical,
Captain
Null is not the same as “optional”
Length
string –› int
“a”
“b”
“c”
null
1
2
3
Null is not allowed
Length
string –› int
“a”
“b”
“c”
null
1
2
3
X
A better way for optional values
+=
“a”
“b”
“c”
“a”
“b”
“c”
missing
or
Tag with “Nothing”
type OptionalString =
| SomeString of string
| Nothing
type OptionalInt =
| SomeInt of int
| Nothing
type OptionalString =
| SomeString of string
| Nothing
type OptionalBool =
| SomeBool of bool
| Nothing
Defining optional types
The built-in “Option” type
type PersonalName =
{
FirstName: string
MiddleInitial: string
LastName: string
}
type Option<'T> =
| Some of 'T
| None
The built-in “Option” type
type PersonalName =
{
FirstName: string
MiddleInitial: Option<string>
LastName: string
}
type Option<'T> =
| Some of 'T
| None
The built-in “Option” type
type PersonalName =
{
FirstName: string
MiddleInitial: string option
LastName: string
}
type Option<'T> =
| Some of 'T
| None
Single choice types
type Something =
| ChoiceA of A
type Email =
| Email of string
type CustomerId =
| CustomerId of int
Wrapping primitive types
Is an EmailAddress just a string?
Is a CustomerId just a int?
Use single choice types to keep them distinct
type EmailAddress = EmailAddress of string
type PhoneNumber = PhoneNumber of string
type CustomerId = CustomerId of int
type OrderId = OrderId of int
Creating the EmailAddress type
let createEmailAddress (s:string) =
if Regex.IsMatch(s,@"^S+@S+.S+$")
then (EmailAddress s)
else ?
let createEmailAddress (s:string) =
if Regex.IsMatch(s,@"^S+@S+.S+$")
then Some (EmailAddress s)
else None
createEmailAddress:
string –› EmailAddress
createEmailAddress:
string –› EmailAddress option
Constrained strings
type String50 = String50 of string
let createString50 (s:string) =
if s.Length <= 50
then Some (String50 s)
else None
createString50 :
string –› String50 option
Constrained numbers
+– 999999Qty: Add To Cart
Constrained numbers
type OrderLineQty = OrderLineQty of int
let createOrderLineQty qty =
if qty >0 && qty <= 99
then Some (OrderLineQty qty)
else None
createOrderLineQty:
int –› OrderLineQty option
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
The challenge, revisited
The challenge, revisited
type Contact = {
FirstName: string
MiddleInitial: string option
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
The challenge, revisited
type Contact = {
FirstName: String50
MiddleInitial: String1 option
LastName: String50
EmailAddress: EmailAddress
IsEmailVerified: bool
}
type Contact = {
Name: PersonalName
Email: EmailContactInfo }
The challenge, revisited
type PersonalName = {
FirstName: String50
MiddleInitial: String1 option
LastName: String50 }
type EmailContactInfo = {
EmailAddress: EmailAddress
IsEmailVerified: bool }
Encoding domain logic
Rule 1: If the email is changed, the verified flag
must be reset to false.
Rule 2: The verified flag can only be set by a
special verification service
type EmailContactInfo = {
EmailAddress: EmailAddress
IsEmailVerified: bool }
Encoding domain logic
type VerifiedEmail =VerifiedEmail of EmailAddress
type EmailContactInfo =
| Unverified of EmailAddress
| Verified ofVerifiedEmail
type VerificationService =
(EmailAddress * VerificationHash) –› VerifiedEmail option
type EmailAddress = ...
type VerifiedEmail =
VerifiedEmail of EmailAddress
type EmailContactInfo =
| Unverified of EmailAddress
|Verified ofVerifiedEmail
The challenge, completed
type PersonalName = {
FirstName: String50
MiddleInitial: String1 option
LastName: String50 }
type Contact = {
Name: PersonalName
Email: EmailContactInfo }
Making illegal states unrepresentable
type Contact = {
Name: Name
Email: EmailContactInfo
Address: PostalContactInfo
}
Making illegal states unrepresentable
type Contact = {
Name: Name
Email: EmailContactInfo
Address: PostalContactInfo
}
New rule:
“A contact must have an email or a postal address”
Making illegal states unrepresentable
type Contact = {
Name: Name
Email: EmailContactInfo option
Address: PostalContactInfo option
}
New rule:
“A contact must have an email or a postal address”
Making illegal states unrepresentable
“A contact must have an email or a postal address”
implies:
• email address only, or
• postal address only, or
• both email address and postal address
Making illegal states unrepresentable
type ContactInfo =
| EmailOnly of EmailContactInfo
| AddrOnly of PostalContactInfo
| EmailAndAddr of EmailContactInfo * PostalContactInfo
type Contact = {
Name: Name
ContactInfo : ContactInfo }
“A contact must have an email or a postal address”
Making illegal states unrepresentable
type Contact = {
Name: Name
Email: EmailContactInfo
Address: PostalContactInfo
}
type Contact = {
Name: Name
ContactInfo : ContactInfo }
type ContactInfo =
| EmailOnly of EmailContactInfo
| AddrOnly of PostalContactInfo
| EmailAndAddr of
EmailContactInfo * PostalContactInfo
AFTER: Email and address merged into one type
“A contact must have an email or a postal address”
BEFORE: Email and address separate
Making illegal states unrepresentable
type Contact = {
Name: Name
PrimaryContactInfo: ContactInfo
SecondaryContactInfo: ContactInfo option }
“A contact must have an email or a postal address”“A contact must have at least one way of being contacted”
type ContactInfo =
| Email of EmailContactInfo
| Addr of PostalContactInfo
States and Transitions
Modelling a common scenario
States and transitions
State A State B State C
Transition from A to B
States and transitions
Transition from B to A
Transition
from B to C
States and transitions
Unverified
EmailAddress
Verified
EmailAddress
Verified
States and transitions for email address
Rule: "You can't send a verification message to a verified email"
Rule: "You can't send a password reset message to a unverified email "
States and transitions
Undelivered
Out for
delivery
Delivered
Put on truck
Address not found
Signed for
States and transitions for shipments
Rule: "You can't put a package on a truck if it is already out for delivery"
Rule: "You can't sign for a package that is already delivered"
States and transitions
Empty Cart Active Cart Paid Cart
Add Item
Remove Item
Pay
Add Item
Remove Item
States and transitions for shopping cart
Rule: "You can't remove an item from an empty cart"
Rule: "You can't change a paid cart"
Rule: "You can't pay for a cart twice"
States and transitions
Empty Cart Active Cart Paid Cart
Add Item
Remove Item
Pay
Add Item
Remove Item
States and transitions for shopping cart
type ActiveCartData =
{ UnpaidItems: Item list }
type PaidCartData =
{ PaidItems: Item list;
Payment: Payment }
no data
needed
Modelling the shopping cart example
type ActiveCartData =
{ UnpaidItems: Item list }
type PaidCartData =
{ PaidItems: Item list; Payment: Payment}
type ShoppingCart =
| EmptyCart // no data
| ActiveCart of ActiveCartData
| PaidCart of PaidCartData
Empty
Cart
Active
Cart
Paid
Cart
Add Item
Remove Item
Pay
Add Item
Remove Item
Shopping cart example
initCart :
Item –› ShoppingCart
addToActive:
(ActiveCartData * Item) –› ShoppingCart
removeFromActive:
(ActiveCartData * Item) –› ShoppingCart
pay:
(ActiveCartData * Payment) –› ShoppingCart
Shopping Cart API
Empty
Cart
Active
Cart
Paid
Cart
Add Item
Remove Item
Pay
Add Item
Remove Item
Shopping cart example
let initCart item =
{ UnpaidItems=[item] }
let addToActive (cart:ActiveCart) item =
{ cart with UnpaidItems = item :: cart.existingItems }
Server code to add an item
Shopping cart example
Client code to add an item using the API
let addItem cart item =
match cart with
| EmptyCart –›
initCart item
| ActiveCart activeData –›
addToActive(activeData,item)
| PaidCart paidData –›
???
Shopping cart example
let removeFromActive (cart:ActiveCart) item =
let remainingItems =
removeFromList cart.existingItems item
match remainingItems with
| [ ] –›
EmptyCart
| _ –›
{cart with UnpaidItems = remainingItems}
Server code to remove an item
Shopping cart example
Client code to remove an item using the API
let removeItem cart item =
match cart with
| EmptyCart –›
???
| ActiveCart activeData –›
removeFromActive(activeData,item)
| PaidCart paidData –›
???
Why design with state transitions?
• Each state can have different allowable data.
• All states are explicitly documented.
• All transitions are explicitly documented.
• It is a design tool that forces you to think about
every possibility that could occur.
Undelivered Out for
delivery
Delivered
Put on
truck
Address not
found
Signed for
Review
What I covered in this talk:
• Ubiquitous language
– Self-documenting designs
• Algebraic types
– products and sums
• Designing with types
– Options instead of null
– Single case unions
– Choices rather than inheritance
– Making illegal states unrepresentable
• States and transitions
Stuff I haven’t had time to cover:
• Services
• CQRS
• The functional approach to use cases
• Domain events
• Error handling
• And much more...
F# is low risk
F# is the safe choice for functional-first development
credit: @7sharp9 @MattDrivenDev
Enterprise
development
F# on over
2 billion devices
Mobile
development
Need to persuade your manager? -> FPbridge.co.uk/why-fsharp.html
Domain Driven Design with the F# type system
DDD in F# resources
fsharpforfunandprofit.com/ddd
gorodinski.com
tomasp.net/blog/type-first-development.aspx/
#fsharp on Twitter
Contact me
@ScottWlaschin
FPbridge.co.uk

More Related Content

What's hot

オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
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
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意Yoshitaka Kawashima
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of CompositionScott Wlaschin
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)lestrrat
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話Yoshitaka Kawashima
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方増田 亨
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Scott Wlaschin
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し増田 亨
 
Elixirと他言語の比較的紹介 ver.2
Elixirと他言語の比較的紹介ver.2Elixirと他言語の比較的紹介ver.2
Elixirと他言語の比較的紹介 ver.2Tsunenori Oohara
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)Mikiya Okuno
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知るShuhei Fujita
 

What's hot (20)

Tackling Complexity
Tackling ComplexityTackling Complexity
Tackling Complexity
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
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)
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of Composition
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し
 
Elixirと他言語の比較的紹介 ver.2
Elixirと他言語の比較的紹介ver.2Elixirと他言語の比較的紹介ver.2
Elixirと他言語の比較的紹介 ver.2
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知る
 

Similar to Domain Driven Design with the F# type System -- F#unctional Londoners 2014

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
 
TypeScript by Howard
TypeScript by HowardTypeScript by Howard
TypeScript by HowardLearningTech
 
Howard type script
Howard   type scriptHoward   type script
Howard type scriptLearningTech
 
Type script by Howard
Type script by HowardType script by Howard
Type script by HowardLearningTech
 
Linq And Its Impact On The.Net Framework
Linq And Its Impact On The.Net FrameworkLinq And Its Impact On The.Net Framework
Linq And Its Impact On The.Net Frameworkrushputin
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScriptGarth Gilmour
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerSrikanth Shreenivas
 
I have the following code and I need to know why I am receiving the .pdf
I have the following code and I need to know why I am receiving the .pdfI have the following code and I need to know why I am receiving the .pdf
I have the following code and I need to know why I am receiving the .pdfezzi552
 
Getting the following errorsError 1 error C2436 {ctor} mem.pdf
Getting the following errorsError 1 error C2436 {ctor}  mem.pdfGetting the following errorsError 1 error C2436 {ctor}  mem.pdf
Getting the following errorsError 1 error C2436 {ctor} mem.pdfherminaherman
 
Speed up the mobile development process
Speed up the mobile development processSpeed up the mobile development process
Speed up the mobile development processLeonardoSarra
 
IntroToCSharpcode.ppt
IntroToCSharpcode.pptIntroToCSharpcode.ppt
IntroToCSharpcode.pptpsundarau
 
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo....NET Conf UY
 
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27Ruby Meditation
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsAlfonso Peletier
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with framelessMiguel Pérez Pasalodos
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядомAndrey Akinshin
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaiMasters
 

Similar to Domain Driven Design with the F# type System -- F#unctional Londoners 2014 (20)

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
 
TypeScript by Howard
TypeScript by HowardTypeScript by Howard
TypeScript by Howard
 
Howard type script
Howard   type scriptHoward   type script
Howard type script
 
Type script by Howard
Type script by HowardType script by Howard
Type script by Howard
 
Linq And Its Impact On The.Net Framework
Linq And Its Impact On The.Net FrameworkLinq And Its Impact On The.Net Framework
Linq And Its Impact On The.Net Framework
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
 
I have the following code and I need to know why I am receiving the .pdf
I have the following code and I need to know why I am receiving the .pdfI have the following code and I need to know why I am receiving the .pdf
I have the following code and I need to know why I am receiving the .pdf
 
Functional DDD
Functional DDDFunctional DDD
Functional DDD
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Getting the following errorsError 1 error C2436 {ctor} mem.pdf
Getting the following errorsError 1 error C2436 {ctor}  mem.pdfGetting the following errorsError 1 error C2436 {ctor}  mem.pdf
Getting the following errorsError 1 error C2436 {ctor} mem.pdf
 
Speed up the mobile development process
Speed up the mobile development processSpeed up the mobile development process
Speed up the mobile development process
 
IntroToCSharpcode.ppt
IntroToCSharpcode.pptIntroToCSharpcode.ppt
IntroToCSharpcode.ppt
 
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
 
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with frameless
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 

More from 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
 
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
 
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
 
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
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)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
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 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
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)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
 
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
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with CapabilitiesScott Wlaschin
 
Dr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterDr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterScott Wlaschin
 
Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeScott 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
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 

More from Scott Wlaschin (20)

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...
 
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
 
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)
 
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)
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 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)
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
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)
 
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
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with Capabilities
 
Dr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterDr Frankenfunctor and the Monadster
Dr Frankenfunctor and the Monadster
 
Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-Toe
 
An introduction to property based testing
An introduction to property based testingAn introduction to property based testing
An introduction to property based testing
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
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
 

Recently uploaded

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
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
 
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
 
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 Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
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
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
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
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Recently uploaded (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
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
 
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
 
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 Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
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...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

Domain Driven Design with the F# type System -- F#unctional Londoners 2014

  • 1. type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool } // true if ownership of // email address is confirmed Domain Driven Design with the F# type system Prologue: how many things are wrong?
  • 2. type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool } Prologue: which values are optional?
  • 3. type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool } Prologue: what are the constraints?
  • 4. type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool } Prologue: what groups are atomic?
  • 5. type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool } Prologue: domain logic?
  • 6. Prologue: F# can help type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool }
  • 7. Domain Driven Design with the F# type system ScottWlaschin @ScottWlaschin fsharpforfunandprofit.com FPbridge.co.uk /ddd
  • 10. What I’m going talk about: • Demystifying functional programming • Functional programming for real world applications • F# vs. C# for domain driven design • Understanding the F# type system • Designing with types
  • 16. Functional programming for real world applications
  • 17. Functional programming is... ... good for mathematical and scientific tasks ... good for complicated algorithms ... really good for parallel processing ... but you need a PhD in computer science 
  • 18. Functional programming is good for... Boring Line Of Business Applications (BLOBAs)
  • 19. Must haves for BLOBA development... • Express requirements clearly • Rapid development cycle • High quality deliverables • Fun
  • 20.
  • 21. F# vs. C# for Domain Driven Design A simple immutable object
  • 22. How do you implement a Value object? Equality based on comparing all properties PersonalName: FirstName = "Alice" LastName = "Adams" PersonalName: FirstName = "Alice" LastName = "Adams"Equal Therefore must be immutable
  • 23. class PersonalName { public PersonalName(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } public string FirstName { get; private set; } public string LastName { get; private set; } } Value object definition in C#
  • 24. class PersonalName { public PersonalName(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } public string FirstName { get; private set; } public string LastName { get; private set; } } Value object definition in C#
  • 25. class PersonalName { // all the code from above, plus... public override int GetHashCode() { return this.FirstName.GetHashCode() + this.LastName.GetHashCode(); } public override bool Equals(object other) { return Equals(other as PersonalName); } public bool Equals(PersonalName other) { if ((object) other == null) { return false; } return FirstName == other.FirstName && LastName == other.LastName; } Value object definition in C# (extra code for equality)
  • 26. type PersonalName = {FirstName:string; LastName:string} Value object definition in F#
  • 27. This page intentionally left blank Value object definition in F# (extra code for equality)
  • 28. How do you implement an Entity object? Equality based on some sort of id Person: Id = 1 Name = "Alice Adams" Person: Id = 1 Name = "Bilbo Baggins" Equal X  Generally has mutable content
  • 29. class Person { public Person(int id, PersonalName name) { this.Id = id; this.Name = name; } public int Id { get; private set; } public PersonalName Name { get; set; } } Entity object definition in C# (part 1)
  • 30. class Person { // all the code from above, plus... public override int GetHashCode() { return this.Id.GetHashCode(); } public override bool Equals(object other) { return Equals(other as Person); } public bool Equals(Person other) { if ((object) other == null) { return false; } return Id == other.Id; } } Entity object definition in C# (part 2)
  • 31. [<CustomEquality; NoComparison>] type Person = {Id:int; Name:PersonalName} with override this.GetHashCode() = hash this.Id override this.Equals(other) = match other with | :? Person as p -> (this.Id = p.Id) | _ -> false Entity object definition in F# with equality override
  • 32. Entity object definition in F# with no equality allowed [<CustomEquality; NoComparison>] type Person = {Id:int; Name:PersonalName} [<NoEquality; NoComparison>]
  • 33. type Person = { ... ... ... } let tryCreatePerson name = // validate on construction // if input is valid return something // if input is not valid return error   Advantages of immutability
  • 34. class PersonalName { public PersonalName(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } public string FirstName { get; private set; } public string LastName { get; private set; } public override int GetHashCode() { return this.FirstName.GetHashCode() + this.LastName.GetHashCode(); } public override bool Equals(object other) { return Equals(other as PersonalName); } public bool Equals(PersonalName other) { if ((object) other == null) { return false; } return FirstName == other.FirstName && LastName == other.LastName; } } Reviewing the C# code so far... class Person { public Person(int id, PersonalName name) { this.Id = id; this.Name = name; } public int Id { get; private set; } public PersonalName Name { get; set; } public override int GetHashCode() { return this.Id.GetHashCode(); } public override bool Equals(object other) { return Equals(other as Person); } public bool Equals(Person other) { if ((object) other == null) { return false; } return Id == other.Id; } } : IValue : IEntity
  • 35. [<StructuralEquality;NoComparison>] type PersonalName = { FirstName : string; LastName : string } Reviewing the F# code so far... [<NoEquality; NoComparison>] type Person = { Id : int; Name : PersonalName }
  • 36. Comparing C# vs. F# C# F# Value objects? Non-trivial Easy Entity objects? Non-trivial Easy Value objects by default? No Yes Immutable objects by default? No Yes Can you tellValue objects from Entities at a glance? No Yes Understandable by non-programmer? No Yes C# vs. F# for DDD
  • 37. F# for Domain Driven Design Communicating a domain model
  • 39. Communication in DDD: “Bounded Context” Business Chemistry un-ionizeunionize Supermarket Email System SpamSpam
  • 40. Communication in DDD: “Bounded Context” Business Chemistry un-ionizeunionize Supermarket Email System SpamSpam Sales Warehouse ProductProduct
  • 41. Communication in DDD: “Bounded Context” Business Chemistry un-ionizeunionize Supermarket Email System SpamSpam Sales Warehouse ProductProduct Marketing Finance CustomerCustomer
  • 42. Communication in DDD: “Ubiquitous Language” Chemistry Ion Atom Molecule Polymer Compound Bond
  • 43. Communication in DDD: “Ubiquitous Language” Chemistry Ion Atom Molecule Polymer Compound Bond Sales Product Promotion Customer Tracking
  • 44. Communication in DDD: “Ubiquitous Language” Chemistry Ion Atom Molecule Polymer Compound Bond Sales Product Promotion Customer Tracking Warehouse Product Stock Transfer Depot Tracking
  • 45. module CardGame = type Suit = Club | Diamond | Spade | Heart type Rank = Two |Three | Four | Five | Six | Seven | Eight | Nine |Ten | Jack | Queen | King | Ace type Card = Suit * Rank type Hand = Card list type Deck = Card list type Player = {Name:string; Hand:Hand} type Game = {Deck:Deck; Players: Player list} type Deal = Deck –› (Deck * Card) type PickupCard = (Hand * Card) –› Hand '*' means a pair. Choose one from each type Ubiquitouslanguage list type is built in
  • 46. module CardGame = type Suit = Club | Diamond | Spade | Heart type Rank = Two |Three | Four | Five | Six | Seven | Eight | Nine |Ten | Jack | Queen | King | Ace type Card = Suit * Rank type Hand = Card list type Deck = Card list type Player = {Name:string; Hand:Hand} type Game = {Deck:Deck; Players: Player list} type Deal = Deck –› (Deck * Card) type PickupCard = (Hand * Card) –› Hand
  • 47. module CardGame = type Suit = Club | Diamond | Spade | Heart type Rank = Two |Three | Four | Five | Six | Seven | Eight | Nine |Ten | Jack | Queen | King | Ace type Card = Suit * Rank type Hand = Card list type Deck = Card list type Player = {Name:string; Hand:Hand} type Game = {Deck:Deck; Players: Player list} type Deal = Deck –› (Deck * Card) type PickupCard = (Hand * Card) –› Hand
  • 48.
  • 49. Understanding the F# type system An introduction to “algebraic” typesAn introduction to “algebraic” types
  • 51. Creating new types New types are constructed by combining other types using two basic operations: type typeW = typeX "times" typeY type typeZ = typeX "plus" typeY
  • 52. Creating new types (a function)AddOneAddOne int –› int 1 2 3 4 2 3 4 5
  • 53. Representing pairs AddPair ? –› int (1,2) (2,3) (3,4) (4,5) 3 5 7 9
  • 55. Representing pairs ×= (true, false) (true, true) (false, false) (false, true) true false true false
  • 56. Representing pairs pair of ints written int * int pair of bools written bool * bool
  • 57. Using tuples for data ×= Alice, Jan 12th Bob, Feb 2nd Carol, Mar 3rd Set of people Set of dates
  • 58. Using tuples for data ×= Alice, Jan 12th Bob, Feb 2nd Carol, Mar 3rd Set of people Set of dates type Birthday = Person * Date
  • 59. Representing a choice Temp F IsFever ? –› bool true false Temp C or
  • 60. Representing a choice += 98˚ F 99˚ F 100˚ F 101˚ F 37.0˚ C 37.5˚ C 38.0˚ C 38.5˚ C Temp F Temp C or
  • 61. Representing a choice += 98˚ F 99˚ F 100˚ F 101˚ F 37.0˚ C 37.5˚ C 38.0˚ C 38.5˚ C Temp F Temp C or Tag these with “C” typeTemp = | F of int | C of float
  • 62. Using choices for data type PaymentMethod = | Cash | Cheque of int | Card of CardType * CardNumber
  • 63. Working with a choice type type PaymentMethod = | Cash | Cheque of int | Card of CardType * CardNumber let printPayment method = match method with | Cash –› printfn “Paid in cash" | Cheque checkNo –› printfn “Paid by cheque: %i" checkNo | Card (cardType,cardNo) –› printfn “Paid with %A %A" cardType cardNo
  • 64. Using choices vs. inheritance interface IPaymentMethod {..} class Cash : IPaymentMethod {..} class Cheque : IPaymentMethod {..} class Card : IPaymentMethod {..} type PaymentMethod = | Cash | Cheque of int | Card of CardType * CardNumber class Evil : IPaymentMethod {..} Data and code is scattered around many locations What goes in here? What is the common behaviour? OO version:
  • 65. Summary: What are types for in FP? An annotation to a value for type checking type AddOne: int –› int Domain modelling tool type Deal = Deck –› (Deck * Card)
  • 66. TYPE ALL THE THINGS
  • 67. Designing with types What can we do with this type system?
  • 68. Required vs. Optional type PersonalName = { FirstName: string; MiddleInitial: string; LastName: string; } required required optional
  • 69. Null is not the same as “optional” Length string –› int “a” “b” “c” 1 2 3 “a” “b” “c” null
  • 70. Spock, set phasers to null! That is illogical, Captain
  • 71. Null is not the same as “optional” Length string –› int “a” “b” “c” null 1 2 3
  • 72.
  • 73. Null is not allowed Length string –› int “a” “b” “c” null 1 2 3 X
  • 74. A better way for optional values += “a” “b” “c” “a” “b” “c” missing or Tag with “Nothing” type OptionalString = | SomeString of string | Nothing
  • 75. type OptionalInt = | SomeInt of int | Nothing type OptionalString = | SomeString of string | Nothing type OptionalBool = | SomeBool of bool | Nothing Defining optional types
  • 76. The built-in “Option” type type PersonalName = { FirstName: string MiddleInitial: string LastName: string } type Option<'T> = | Some of 'T | None
  • 77. The built-in “Option” type type PersonalName = { FirstName: string MiddleInitial: Option<string> LastName: string } type Option<'T> = | Some of 'T | None
  • 78. The built-in “Option” type type PersonalName = { FirstName: string MiddleInitial: string option LastName: string } type Option<'T> = | Some of 'T | None
  • 79. Single choice types type Something = | ChoiceA of A type Email = | Email of string type CustomerId = | CustomerId of int
  • 80. Wrapping primitive types Is an EmailAddress just a string? Is a CustomerId just a int? Use single choice types to keep them distinct type EmailAddress = EmailAddress of string type PhoneNumber = PhoneNumber of string type CustomerId = CustomerId of int type OrderId = OrderId of int
  • 81. Creating the EmailAddress type let createEmailAddress (s:string) = if Regex.IsMatch(s,@"^S+@S+.S+$") then (EmailAddress s) else ? let createEmailAddress (s:string) = if Regex.IsMatch(s,@"^S+@S+.S+$") then Some (EmailAddress s) else None createEmailAddress: string –› EmailAddress createEmailAddress: string –› EmailAddress option
  • 82. Constrained strings type String50 = String50 of string let createString50 (s:string) = if s.Length <= 50 then Some (String50 s) else None createString50 : string –› String50 option
  • 84. Constrained numbers type OrderLineQty = OrderLineQty of int let createOrderLineQty qty = if qty >0 && qty <= 99 then Some (OrderLineQty qty) else None createOrderLineQty: int –› OrderLineQty option
  • 85. type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool } The challenge, revisited
  • 86. The challenge, revisited type Contact = { FirstName: string MiddleInitial: string option LastName: string EmailAddress: string IsEmailVerified: bool }
  • 87. The challenge, revisited type Contact = { FirstName: String50 MiddleInitial: String1 option LastName: String50 EmailAddress: EmailAddress IsEmailVerified: bool }
  • 88.
  • 89. type Contact = { Name: PersonalName Email: EmailContactInfo } The challenge, revisited type PersonalName = { FirstName: String50 MiddleInitial: String1 option LastName: String50 } type EmailContactInfo = { EmailAddress: EmailAddress IsEmailVerified: bool }
  • 90. Encoding domain logic Rule 1: If the email is changed, the verified flag must be reset to false. Rule 2: The verified flag can only be set by a special verification service type EmailContactInfo = { EmailAddress: EmailAddress IsEmailVerified: bool }
  • 91. Encoding domain logic type VerifiedEmail =VerifiedEmail of EmailAddress type EmailContactInfo = | Unverified of EmailAddress | Verified ofVerifiedEmail type VerificationService = (EmailAddress * VerificationHash) –› VerifiedEmail option
  • 92. type EmailAddress = ... type VerifiedEmail = VerifiedEmail of EmailAddress type EmailContactInfo = | Unverified of EmailAddress |Verified ofVerifiedEmail The challenge, completed type PersonalName = { FirstName: String50 MiddleInitial: String1 option LastName: String50 } type Contact = { Name: PersonalName Email: EmailContactInfo }
  • 93. Making illegal states unrepresentable type Contact = { Name: Name Email: EmailContactInfo Address: PostalContactInfo }
  • 94. Making illegal states unrepresentable type Contact = { Name: Name Email: EmailContactInfo Address: PostalContactInfo } New rule: “A contact must have an email or a postal address”
  • 95. Making illegal states unrepresentable type Contact = { Name: Name Email: EmailContactInfo option Address: PostalContactInfo option } New rule: “A contact must have an email or a postal address”
  • 96. Making illegal states unrepresentable “A contact must have an email or a postal address” implies: • email address only, or • postal address only, or • both email address and postal address
  • 97. Making illegal states unrepresentable type ContactInfo = | EmailOnly of EmailContactInfo | AddrOnly of PostalContactInfo | EmailAndAddr of EmailContactInfo * PostalContactInfo type Contact = { Name: Name ContactInfo : ContactInfo } “A contact must have an email or a postal address”
  • 98. Making illegal states unrepresentable type Contact = { Name: Name Email: EmailContactInfo Address: PostalContactInfo } type Contact = { Name: Name ContactInfo : ContactInfo } type ContactInfo = | EmailOnly of EmailContactInfo | AddrOnly of PostalContactInfo | EmailAndAddr of EmailContactInfo * PostalContactInfo AFTER: Email and address merged into one type “A contact must have an email or a postal address” BEFORE: Email and address separate
  • 99.
  • 100. Making illegal states unrepresentable type Contact = { Name: Name PrimaryContactInfo: ContactInfo SecondaryContactInfo: ContactInfo option } “A contact must have an email or a postal address”“A contact must have at least one way of being contacted” type ContactInfo = | Email of EmailContactInfo | Addr of PostalContactInfo
  • 101. States and Transitions Modelling a common scenario
  • 102. States and transitions State A State B State C Transition from A to B States and transitions Transition from B to A Transition from B to C
  • 103. States and transitions Unverified EmailAddress Verified EmailAddress Verified States and transitions for email address Rule: "You can't send a verification message to a verified email" Rule: "You can't send a password reset message to a unverified email "
  • 104. States and transitions Undelivered Out for delivery Delivered Put on truck Address not found Signed for States and transitions for shipments Rule: "You can't put a package on a truck if it is already out for delivery" Rule: "You can't sign for a package that is already delivered"
  • 105. States and transitions Empty Cart Active Cart Paid Cart Add Item Remove Item Pay Add Item Remove Item States and transitions for shopping cart Rule: "You can't remove an item from an empty cart" Rule: "You can't change a paid cart" Rule: "You can't pay for a cart twice"
  • 106. States and transitions Empty Cart Active Cart Paid Cart Add Item Remove Item Pay Add Item Remove Item States and transitions for shopping cart type ActiveCartData = { UnpaidItems: Item list } type PaidCartData = { PaidItems: Item list; Payment: Payment } no data needed
  • 107. Modelling the shopping cart example type ActiveCartData = { UnpaidItems: Item list } type PaidCartData = { PaidItems: Item list; Payment: Payment} type ShoppingCart = | EmptyCart // no data | ActiveCart of ActiveCartData | PaidCart of PaidCartData Empty Cart Active Cart Paid Cart Add Item Remove Item Pay Add Item Remove Item
  • 108. Shopping cart example initCart : Item –› ShoppingCart addToActive: (ActiveCartData * Item) –› ShoppingCart removeFromActive: (ActiveCartData * Item) –› ShoppingCart pay: (ActiveCartData * Payment) –› ShoppingCart Shopping Cart API Empty Cart Active Cart Paid Cart Add Item Remove Item Pay Add Item Remove Item
  • 109. Shopping cart example let initCart item = { UnpaidItems=[item] } let addToActive (cart:ActiveCart) item = { cart with UnpaidItems = item :: cart.existingItems } Server code to add an item
  • 110. Shopping cart example Client code to add an item using the API let addItem cart item = match cart with | EmptyCart –› initCart item | ActiveCart activeData –› addToActive(activeData,item) | PaidCart paidData –› ???
  • 111. Shopping cart example let removeFromActive (cart:ActiveCart) item = let remainingItems = removeFromList cart.existingItems item match remainingItems with | [ ] –› EmptyCart | _ –› {cart with UnpaidItems = remainingItems} Server code to remove an item
  • 112. Shopping cart example Client code to remove an item using the API let removeItem cart item = match cart with | EmptyCart –› ??? | ActiveCart activeData –› removeFromActive(activeData,item) | PaidCart paidData –› ???
  • 113. Why design with state transitions? • Each state can have different allowable data. • All states are explicitly documented. • All transitions are explicitly documented. • It is a design tool that forces you to think about every possibility that could occur. Undelivered Out for delivery Delivered Put on truck Address not found Signed for
  • 114. Review What I covered in this talk: • Ubiquitous language – Self-documenting designs • Algebraic types – products and sums • Designing with types – Options instead of null – Single case unions – Choices rather than inheritance – Making illegal states unrepresentable • States and transitions
  • 115. Stuff I haven’t had time to cover: • Services • CQRS • The functional approach to use cases • Domain events • Error handling • And much more...
  • 116. F# is low risk F# is the safe choice for functional-first development credit: @7sharp9 @MattDrivenDev Enterprise development F# on over 2 billion devices Mobile development Need to persuade your manager? -> FPbridge.co.uk/why-fsharp.html
  • 117. Domain Driven Design with the F# type system DDD in F# resources fsharpforfunandprofit.com/ddd gorodinski.com tomasp.net/blog/type-first-development.aspx/ #fsharp on Twitter Contact me @ScottWlaschin FPbridge.co.uk