SlideShare a Scribd company logo
1 of 101
Download to read offline
Prologue: how many things are wrong?

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: 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?
type Contact = {

FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Prologue: F# can help
type Contact = {
FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
Domain Driven Design
with the F# type system
Scott Wlaschin
@ScottWlaschin
fsharpforfunandprofit.com /ddd
What is DDD?

What is F#?

What is DDD and F#?

“F# is a mature, open
source, cross-platform,
functional-first programming
language which empowers
users and organizations to
tackle complex computing
problems with simple,
maintainable and robust
code.”
— fsharp.org
What I’m going talk about:

• Functional programming for real
world applications
• F# vs. C# for domain driven design
• Understanding the F# type system
• Designing with types
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
Values vs. Entities
Values vs. Entities

Photo credit: http://www.flickr.com/photos/anacooke/
Values vs. Entities

Photo credit: http://www.flickr.com/photos/anacooke/
Values vs. Entities

Examples of Values:
• Personal name
• Email address
• Postal address
• Product code
uneaten apple

Examples of Entities:
• Customer
• Order
• Product
half eaten apple
How do you implement a Value object?

Equality based on comparing all properties
PersonalName:
FirstName = "Alice"
LastName = "Adams"

PersonalName:
FirstName = "Alice"
Equal LastName = "Adams"

 Therefore must be immutable
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# (extra code for equality)
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 F#
type PersonalName = {FirstName:string; LastName:string}
Value object definition in F# (extra code for equality)

This page intentionally left blank
How do you implement an Entity object?

Equality based on some sort of id
Person:
Equal Person:
Id = 1
Id = 1
Name = "Alice Adams" X
Name = "Bilbo Baggins"

 Generally has mutable content
Entity object definition in C# (part 1)
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 2)
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 F# with equality override
[<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 no equality allowed
[<CustomEquality; NoComparison>]
[<NoEquality; NoComparison>]
type Person = {Id:int; Name:PersonalName}
Entity immutability
[<NoEquality; NoComparison>]
type Person = { ... ... ... }

let tryCreatePerson name =
// validate on construction
// if input is valid return something
// if input is not valid return error



Entity object definition in F# with mutability
[<NoEquality; NoComparison>]
type Person = {Id:int; mutable Name:PersonalName}
Reviewing the C# code so far...

: IValue

class PersonalName
{
public PersonalName(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}

: IEntity

class Person
{
public Person(int id, PersonalName name)
{
this.Id = id;
this.Name = name;
}

public string FirstName { get; private set; }
public string LastName { get; private set; }

public int Id { get; private set; }
public PersonalName Name { get; set; }

public override int GetHashCode()
{
return this.FirstName.GetHashCode() +
this.LastName.GetHashCode();
}

public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as Person);
}

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;
}
}

public bool Equals(Person other)
{
if ((object) other == null)
{
return false;
}
return Id == other.Id;
}
}
Reviewing the C# code so far...

: IValue

class PersonalName
{
public PersonalName(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}

: IEntity

class Person
{
public Person(int id, PersonalName name)
{
this.Id = id;
this.Name = name;
}

public string FirstName { get; private set; }
public string LastName { get; private set; }

public int Id { get; private set; }
public PersonalName Name { get; set; }

public override int GetHashCode()
{
return this.FirstName.GetHashCode() +
this.LastName.GetHashCode();
}

public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as Person);
}

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;
}
}

public bool Equals(Person other)
{
if ((object) other == null)
{
return false;
}
return Id == other.Id;
}
}
Reviewing the F# code so far...

[<StructuralEquality;NoComparison>]
type PersonalName = {
FirstName : string;
LastName : string }

[<NoEquality; NoComparison>]
type Person = {
Id : int;
Name : PersonalName }
Comparing C# vs. F#

C#

Value objects?
Entity objects?
Value objects by default?
Immutable objects by default?
Can you tell Value objects
from Entities at a glance?
Understandable by
non-programmer?

F#

Non-trivial
Non-trivial
No
No
No

Easy
Easy
Yes
Yes
Yes

No

Yes
F# for Domain Driven Design
Communicating a domain model
Communication is hard...

U-N-I-O-N-I-Z-E
Communication in DDD: “Bounded Context”

Supermarket
Marketing
Sales
Business
Customer
unionize
Product
Spam

Email System
Warehouse
Finance
Chemistry
Customer
un-ionize
Product
Spam
Communication in DDD: “Ubiquitous Language”

Warehouse
Chemistry
Sales
IonProduct MoleculeTransfer Depot Tracking
Product Stock
Atom
Promotion Customer Tracking
Polymer Compound Bond
module CardGame =
type Suit = Club | Diamond | Spade | Heart

Ubiquitous language

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

Ubiquitous language

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

'*' means a pair. Choose one from each type
list type is built in

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
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” types
Understanding the F# type system
An introduction to “composable” types
Composable types
Creating new types in F#

New types in F# are constructed by combining
other types using two basic operations:
type typeW = typeX "times" typeY
type typeZ = typeX "plus" typeY
Creating new types in F#

1
2
3
4

(aAddOne
function)
int –› int

2
3
4
5
Representing pairs

(1,2)
(2,3)
(3,4)
(4,5)

AddPair
? –› int

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

or
Temp C

IsFever
? –› bool

true
false
Representing a choice

Temp F

or
Temp C

98˚ F
99˚ F
100˚ F
101˚ F

= +
37.0˚ C
37.5˚ C
38.0˚ C
38.5˚ C
Representing a choice

Temp F

or
Temp C

98˚ F
99˚ F
100˚ F
101˚ F

= +
37.0˚ C
37.5˚ C
38.0˚ C
38.5˚ C

type Temp =
| F of int
| C of float

Tag these with “C”
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
What are types for in F#?

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
optional
required
Null is not the same as “optional”

“a”
“b”
“c”
null

Length
string –› int

1
2
3
Spock, set
phasers to null!

That is illogical,
Captain
Null is not the same as “optional”

“a”
“b”
“c”
null

Length
string –› int

1
2
3
Null is not allowed in F#

“a”
“b”
“c”
null
X

Length
string –› int

1
2
3
A better way for optional values

“a”
“b”
“c”
or

“a”
“b”
“c”

= +

type OptionalString =
| SomeString of string
| Nothing

missing
Tag with “Nothing”
Defining optional types
type OptionalString =
| SomeString of string
| Nothing
type OptionalInt =
| SomeInt of int
| Nothing

type OptionalBool =
| SomeBool of bool
| Nothing
The built-in “Option” type

type Option<'T> =
| Some of 'T
| None
type PersonalName =
{
FirstName: string
MiddleInitial: string
LastName: string
}
The built-in “Option” type

type Option<'T> =
| Some of 'T
| None
type PersonalName =
{
FirstName: string
MiddleInitial: Option<string>
LastName: string
}
The built-in “Option” type

type Option<'T> =
| Some of 'T
| None
type PersonalName =
{
FirstName: string
MiddleInitial: string option
LastName: string
}
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 ?
createEmailAddress:
string –› EmailAddress
Creating the EmailAddress type

let createEmailAddress (s:string) =
if Regex.IsMatch(s,@"^S+@S+.S+$")
then Some (EmailAddress s)
(EmailAddress s)
else None
?
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

Qty: – 999999 +

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
The challenge, revisited

type Contact = {

FirstName: string
MiddleInitial: string
LastName: string
EmailAddress: string
IsEmailVerified: bool
}
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
}
The challenge, revisited
type PersonalName = {
FirstName: String50
MiddleInitial: String1 option
LastName: String50 }

type Contact = {
Name: PersonalName
Email: EmailContactInfo }

type EmailContactInfo = {
EmailAddress: EmailAddress
IsEmailVerified: bool }
Encoding domain logic

type EmailContactInfo = {
EmailAddress: EmailAddress
IsEmailVerified: bool }
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
Encoding domain logic

type VerifiedEmail = VerifiedEmail of EmailAddress
type VerificationService =
(EmailAddress * VerificationHash) –› VerifiedEmail option

type EmailContactInfo =
| Unverified of EmailAddress
| Verified of VerifiedEmail
The challenge, completed
type EmailAddress = ...
type VerifiedEmail =
VerifiedEmail of EmailAddress

type PersonalName = {
FirstName: String50
MiddleInitial: String1 option
LastName: String50 }

type EmailContactInfo =
| Unverified of EmailAddress
| Verified of VerifiedEmail

type Contact = {
Name: PersonalName
Email: EmailContactInfo }
Making illegal states unrepresentable

New rule:
“A contact must have an email or a postal address”

type Contact = {
Name: Name
Email: EmailContactInfo
Address: PostalContactInfo
}
Making illegal states unrepresentable

New rule:
“A contact must have an email or a postal address”

type Contact = {
Name: Name
Email: EmailContactInfo option
Address: PostalContactInfo option
}
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

“A contact must have an email or a postal address”
type ContactInfo =
| EmailOnly of EmailContactInfo
| AddrOnly of PostalContactInfo
| EmailAndAddr of EmailContactInfo * PostalContactInfo
type Contact = {
Name: Name
ContactInfo : ContactInfo }
Making illegal states unrepresentable

“A contact must have an email or a postal address”
BEFORE: Email and address separate

type Contact = {
Name: Name
Email: EmailContactInfo
Address: PostalContactInfo
}

AFTER: Email and address merged into one type

type Contact = {
Name: Name
ContactInfo : ContactInfo }

type ContactInfo =
| EmailOnly of EmailContactInfo
| AddrOnly of PostalContactInfo
| EmailAndAddr of
EmailContactInfo * PostalContactInfo
Making illegal states unrepresentable

“A contact must have an email or a postal address”
Making illegal states unrepresentable
“A contact must have at leastemail or of postalcontacted”
“A contact must have an one way a being address”
type ContactInfo =
| Email of EmailContactInfo
| Addr of PostalContactInfo
type Contact = {
Name: Name
PrimaryContactInfo: ContactInfo
SecondaryContactInfo: ContactInfo option }
Stuff I haven’t had time to cover:
• Services
• States and transitions
• CQRS
• The functional approach to use cases
• Domain events
• Error handling
• And much more...
F# is low risk

Enterprise
development

Mobile
development

F# on over
2 billion devices

F# is the safe choice for functional-first development

credit: @7sharp9 @MattDrivenDev
Thank you!

fsharpforfunandprofit.com/ddd
fsharp.org/testimonials
tryfsharp.org
try F# in your web browser!

@ScottWlaschin
#fsharp on Twitter

More Related Content

What's hot

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
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)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
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programmingScott Wlaschin
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best PracticesTheo Jungeblut
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean ArchitectureMattia Battiston
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick SmackdownAlexander Ioffe
 
Design functional solutions in Java, a practical example
Design functional solutions in Java, a practical exampleDesign functional solutions in Java, a practical example
Design functional solutions in Java, a practical exampleMarian Wamsiedel
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기OKKY
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionsaber tabatabaee
 
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
 

What's hot (20)

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)
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
Clean code
Clean codeClean code
Clean code
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Clean Code
Clean CodeClean Code
Clean Code
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
 
Design functional solutions in Java, a practical example
Design functional solutions in Java, a practical exampleDesign functional solutions in Java, a practical example
Design functional solutions in Java, a practical example
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English version
 
F# for C# Programmers
F# for C# ProgrammersF# for C# Programmers
F# for C# Programmers
 
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...
 

Similar to Domain Driven Design with the F# type System -- NDC London 2013

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
 
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
 
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
 
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
 
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
 
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
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядомAndrey Akinshin
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented JavascriptDaniel Ku
 
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
 
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
 

Similar to Domain Driven Design with the F# type System -- NDC London 2013 (20)

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
 
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
 
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
 
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
 
recap-js-and-ts.pdf
recap-js-and-ts.pdfrecap-js-and-ts.pdf
recap-js-and-ts.pdf
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
 
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
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
 
Martin Roy Portfolio
Martin Roy PortfolioMartin Roy Portfolio
Martin Roy Portfolio
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented Javascript
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
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
 
Portfolio Martin Roy
Portfolio Martin RoyPortfolio Martin Roy
Portfolio Martin Roy
 
Portfolio Martin Roy
Portfolio Martin RoyPortfolio Martin Roy
Portfolio Martin Roy
 
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...
 

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
 
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
 
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
 
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
 

More from Scott Wlaschin (15)

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...
 
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)
 
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
 
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
 
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
 

Recently uploaded

full stack practical assignment msc cs.pdf
full stack practical assignment msc cs.pdffull stack practical assignment msc cs.pdf
full stack practical assignment msc cs.pdfHulkTheDevil
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024BookNet Canada
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Dublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptxDublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptxKunal Gupta
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
QMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfQMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfROWELL MARQUINA
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceOpsTree solutions
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Tecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for RotogravureTecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for RotogravureAntonio de Llamas
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...amber724300
 
Introduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxIntroduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxmprakaash5
 
Transport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MITransport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MIRomil Mishra
 
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023Joshua Flannery
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
The Critical Role of Spatial Data in Today's Data Ecosystem
The Critical Role of Spatial Data in Today's Data EcosystemThe Critical Role of Spatial Data in Today's Data Ecosystem
The Critical Role of Spatial Data in Today's Data EcosystemSafe Software
 

Recently uploaded (20)

full stack practical assignment msc cs.pdf
full stack practical assignment msc cs.pdffull stack practical assignment msc cs.pdf
full stack practical assignment msc cs.pdf
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Dublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptxDublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptx
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
QMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfQMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdf
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer Experience
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Tecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for RotogravureTecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for Rotogravure
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
 
Introduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxIntroduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptx
 
Transport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MITransport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MI
 
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
The Critical Role of Spatial Data in Today's Data Ecosystem
The Critical Role of Spatial Data in Today's Data EcosystemThe Critical Role of Spatial Data in Today's Data Ecosystem
The Critical Role of Spatial Data in Today's Data Ecosystem
 

Domain Driven Design with the F# type System -- NDC London 2013

  • 1. Prologue: how many things are wrong? 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
  • 2. Prologue: which values are optional? type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool }
  • 3. Prologue: what are the constraints? type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool }
  • 4. Prologue: what groups are atomic? type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool }
  • 5. Prologue: domain logic? type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool }
  • 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 Scott Wlaschin @ScottWlaschin fsharpforfunandprofit.com /ddd
  • 8. What is DDD? What is F#? What is DDD and F#? “F# is a mature, open source, cross-platform, functional-first programming language which empowers users and organizations to tackle complex computing problems with simple, maintainable and robust code.” — fsharp.org
  • 9.
  • 10. What I’m going talk about: • Functional programming for real world applications • F# vs. C# for domain driven design • Understanding the F# type system • Designing with types
  • 11. Functional programming for real world applications
  • 12. 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 
  • 13. Functional programming is good for... Boring Line Of Business Applications (BLOBAs)
  • 14. Must haves for BLOBA development... • Express requirements clearly • Rapid development cycle • High quality deliverables • Fun
  • 15.
  • 16. F# vs. C# for Domain Driven Design Values vs. Entities
  • 17. Values vs. Entities Photo credit: http://www.flickr.com/photos/anacooke/
  • 18. Values vs. Entities Photo credit: http://www.flickr.com/photos/anacooke/
  • 19. Values vs. Entities Examples of Values: • Personal name • Email address • Postal address • Product code uneaten apple Examples of Entities: • Customer • Order • Product half eaten apple
  • 20. How do you implement a Value object? Equality based on comparing all properties PersonalName: FirstName = "Alice" LastName = "Adams" PersonalName: FirstName = "Alice" Equal LastName = "Adams"  Therefore must be immutable
  • 21. 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; } }
  • 22. Value object definition in C# (extra code for equality) 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; }
  • 23. Value object definition in F# type PersonalName = {FirstName:string; LastName:string}
  • 24. Value object definition in F# (extra code for equality) This page intentionally left blank
  • 25. How do you implement an Entity object? Equality based on some sort of id Person: Equal Person: Id = 1 Id = 1 Name = "Alice Adams" X Name = "Bilbo Baggins"  Generally has mutable content
  • 26. Entity object definition in C# (part 1) 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; } }
  • 27. Entity object definition in C# (part 2) 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; } }
  • 28. Entity object definition in F# with equality override [<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
  • 29. Entity object definition in F# with no equality allowed [<CustomEquality; NoComparison>] [<NoEquality; NoComparison>] type Person = {Id:int; Name:PersonalName}
  • 30. Entity immutability [<NoEquality; NoComparison>] type Person = { ... ... ... } let tryCreatePerson name = // validate on construction // if input is valid return something // if input is not valid return error  
  • 31.
  • 32. Entity object definition in F# with mutability [<NoEquality; NoComparison>] type Person = {Id:int; mutable Name:PersonalName}
  • 33. Reviewing the C# code so far... : IValue class PersonalName { public PersonalName(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } : IEntity class Person { public Person(int id, PersonalName name) { this.Id = id; this.Name = name; } public string FirstName { get; private set; } public string LastName { get; private set; } public int Id { get; private set; } public PersonalName Name { get; set; } public override int GetHashCode() { return this.FirstName.GetHashCode() + this.LastName.GetHashCode(); } public override int GetHashCode() { return this.Id.GetHashCode(); } public override bool Equals(object other) { return Equals(other as Person); } 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; } } public bool Equals(Person other) { if ((object) other == null) { return false; } return Id == other.Id; } }
  • 34. Reviewing the C# code so far... : IValue class PersonalName { public PersonalName(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } : IEntity class Person { public Person(int id, PersonalName name) { this.Id = id; this.Name = name; } public string FirstName { get; private set; } public string LastName { get; private set; } public int Id { get; private set; } public PersonalName Name { get; set; } public override int GetHashCode() { return this.FirstName.GetHashCode() + this.LastName.GetHashCode(); } public override int GetHashCode() { return this.Id.GetHashCode(); } public override bool Equals(object other) { return Equals(other as Person); } 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; } } public bool Equals(Person other) { if ((object) other == null) { return false; } return Id == other.Id; } }
  • 35. Reviewing the F# code so far... [<StructuralEquality;NoComparison>] type PersonalName = { FirstName : string; LastName : string } [<NoEquality; NoComparison>] type Person = { Id : int; Name : PersonalName }
  • 36. Comparing C# vs. F# C# Value objects? Entity objects? Value objects by default? Immutable objects by default? Can you tell Value objects from Entities at a glance? Understandable by non-programmer? F# Non-trivial Non-trivial No No No Easy Easy Yes Yes Yes No Yes
  • 37. F# for Domain Driven Design Communicating a domain model
  • 39. Communication in DDD: “Bounded Context” Supermarket Marketing Sales Business Customer unionize Product Spam Email System Warehouse Finance Chemistry Customer un-ionize Product Spam
  • 40. Communication in DDD: “Ubiquitous Language” Warehouse Chemistry Sales IonProduct MoleculeTransfer Depot Tracking Product Stock Atom Promotion Customer Tracking Polymer Compound Bond
  • 41. module CardGame = type Suit = Club | Diamond | Spade | Heart Ubiquitous language 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
  • 42. module CardGame = type Suit = Club | Diamond | Spade | Heart Ubiquitous language 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 '*' means a pair. Choose one from each type list type is built in type Player = {Name:string; Hand:Hand} type Game = {Deck:Deck; Players: Player list} type Deal = Deck –› (Deck * Card) type PickupCard = (Hand * Card) –› Hand
  • 43. 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
  • 44. 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
  • 45.
  • 46. Understanding the F# type system An introduction to “algebraic” types
  • 47. Understanding the F# type system An introduction to “composable” types
  • 49. Creating new types in F# New types in F# are constructed by combining other types using two basic operations: type typeW = typeX "times" typeY type typeZ = typeX "plus" typeY
  • 50. Creating new types in F# 1 2 3 4 (aAddOne function) int –› int 2 3 4 5
  • 53. Representing pairs (true, false) (true, true) (false, false) (false, true) = true false × true false
  • 54. Representing pairs pair of ints written int * int pair of bools written bool * bool
  • 55. Using tuples for data Alice, Jan 12th Bob, Feb 2nd Carol, Mar 3rd = Set of people × Set of dates
  • 56. Using tuples for data Alice, Jan 12th Bob, Feb 2nd Carol, Mar 3rd = Set of people × Set of dates type Birthday = Person * Date
  • 57. Representing a choice Temp F or Temp C IsFever ? –› bool true false
  • 58. Representing a choice Temp F or Temp C 98˚ F 99˚ F 100˚ F 101˚ F = + 37.0˚ C 37.5˚ C 38.0˚ C 38.5˚ C
  • 59. Representing a choice Temp F or Temp C 98˚ F 99˚ F 100˚ F 101˚ F = + 37.0˚ C 37.5˚ C 38.0˚ C 38.5˚ C type Temp = | F of int | C of float Tag these with “C”
  • 60. Using choices for data type PaymentMethod = | Cash | Cheque of int | Card of CardType * CardNumber
  • 61. 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
  • 62. What are types for in F#? An annotation to a value for type checking type AddOne: int –› int Domain modelling tool type Deal = Deck –› (Deck * Card)
  • 63. TYPE ALL THE THINGS
  • 64. Designing with types What can we do with this type system?
  • 65. Required vs. Optional type PersonalName = { FirstName: string; MiddleInitial: string; LastName: string; } required optional required
  • 66. Null is not the same as “optional” “a” “b” “c” null Length string –› int 1 2 3
  • 67. Spock, set phasers to null! That is illogical, Captain
  • 68. Null is not the same as “optional” “a” “b” “c” null Length string –› int 1 2 3
  • 69.
  • 70. Null is not allowed in F# “a” “b” “c” null X Length string –› int 1 2 3
  • 71. A better way for optional values “a” “b” “c” or “a” “b” “c” = + type OptionalString = | SomeString of string | Nothing missing Tag with “Nothing”
  • 72. Defining optional types type OptionalString = | SomeString of string | Nothing type OptionalInt = | SomeInt of int | Nothing type OptionalBool = | SomeBool of bool | Nothing
  • 73. The built-in “Option” type type Option<'T> = | Some of 'T | None type PersonalName = { FirstName: string MiddleInitial: string LastName: string }
  • 74. The built-in “Option” type type Option<'T> = | Some of 'T | None type PersonalName = { FirstName: string MiddleInitial: Option<string> LastName: string }
  • 75. The built-in “Option” type type Option<'T> = | Some of 'T | None type PersonalName = { FirstName: string MiddleInitial: string option LastName: string }
  • 76. Single choice types type Something = | ChoiceA of A type Email = | Email of string type CustomerId = | CustomerId of int
  • 77. 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
  • 78. Creating the EmailAddress type let createEmailAddress (s:string) = if Regex.IsMatch(s,@"^S+@S+.S+$") then (EmailAddress s) else ? createEmailAddress: string –› EmailAddress
  • 79. Creating the EmailAddress type let createEmailAddress (s:string) = if Regex.IsMatch(s,@"^S+@S+.S+$") then Some (EmailAddress s) (EmailAddress s) else None ? createEmailAddress: string –› EmailAddress option
  • 80. 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
  • 81. Constrained numbers Qty: – 999999 + Add To Cart
  • 82. 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
  • 83. The challenge, revisited type Contact = { FirstName: string MiddleInitial: string LastName: string EmailAddress: string IsEmailVerified: bool }
  • 84. The challenge, revisited type Contact = { FirstName: string MiddleInitial: string option LastName: string EmailAddress: string IsEmailVerified: bool }
  • 85. The challenge, revisited type Contact = { FirstName: String50 MiddleInitial: String1 option LastName: String50 EmailAddress: EmailAddress IsEmailVerified: bool }
  • 86.
  • 87. The challenge, revisited type PersonalName = { FirstName: String50 MiddleInitial: String1 option LastName: String50 } type Contact = { Name: PersonalName Email: EmailContactInfo } type EmailContactInfo = { EmailAddress: EmailAddress IsEmailVerified: bool }
  • 88. Encoding domain logic type EmailContactInfo = { EmailAddress: EmailAddress IsEmailVerified: bool } 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
  • 89. Encoding domain logic type VerifiedEmail = VerifiedEmail of EmailAddress type VerificationService = (EmailAddress * VerificationHash) –› VerifiedEmail option type EmailContactInfo = | Unverified of EmailAddress | Verified of VerifiedEmail
  • 90. The challenge, completed type EmailAddress = ... type VerifiedEmail = VerifiedEmail of EmailAddress type PersonalName = { FirstName: String50 MiddleInitial: String1 option LastName: String50 } type EmailContactInfo = | Unverified of EmailAddress | Verified of VerifiedEmail type Contact = { Name: PersonalName Email: EmailContactInfo }
  • 91. Making illegal states unrepresentable New rule: “A contact must have an email or a postal address” type Contact = { Name: Name Email: EmailContactInfo Address: PostalContactInfo }
  • 92. Making illegal states unrepresentable New rule: “A contact must have an email or a postal address” type Contact = { Name: Name Email: EmailContactInfo option Address: PostalContactInfo option }
  • 93. 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
  • 94. Making illegal states unrepresentable “A contact must have an email or a postal address” type ContactInfo = | EmailOnly of EmailContactInfo | AddrOnly of PostalContactInfo | EmailAndAddr of EmailContactInfo * PostalContactInfo type Contact = { Name: Name ContactInfo : ContactInfo }
  • 95. Making illegal states unrepresentable “A contact must have an email or a postal address” BEFORE: Email and address separate type Contact = { Name: Name Email: EmailContactInfo Address: PostalContactInfo } AFTER: Email and address merged into one type type Contact = { Name: Name ContactInfo : ContactInfo } type ContactInfo = | EmailOnly of EmailContactInfo | AddrOnly of PostalContactInfo | EmailAndAddr of EmailContactInfo * PostalContactInfo
  • 96.
  • 97. Making illegal states unrepresentable “A contact must have an email or a postal address”
  • 98. Making illegal states unrepresentable “A contact must have at leastemail or of postalcontacted” “A contact must have an one way a being address” type ContactInfo = | Email of EmailContactInfo | Addr of PostalContactInfo type Contact = { Name: Name PrimaryContactInfo: ContactInfo SecondaryContactInfo: ContactInfo option }
  • 99. Stuff I haven’t had time to cover: • Services • States and transitions • CQRS • The functional approach to use cases • Domain events • Error handling • And much more...
  • 100. F# is low risk Enterprise development Mobile development F# on over 2 billion devices F# is the safe choice for functional-first development credit: @7sharp9 @MattDrivenDev
  • 101. Thank you! fsharpforfunandprofit.com/ddd fsharp.org/testimonials tryfsharp.org try F# in your web browser! @ScottWlaschin #fsharp on Twitter