SlideShare a Scribd company logo
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
Domain Driven Design with the F# type System -- NDC London 2013
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
Domain Driven Design with the F# type System -- NDC London 2013
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



Domain Driven Design with the F# type System -- NDC London 2013
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
Domain Driven Design with the F# type System -- NDC London 2013
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
Domain Driven Design with the F# type System -- NDC London 2013
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
}
Domain Driven Design with the F# type System -- NDC London 2013
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
Domain Driven Design with the F# type System -- NDC London 2013
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

PDF
The Power of Composition (NDC Oslo 2020)
Scott Wlaschin
 
PDF
Railway Oriented Programming
Scott Wlaschin
 
PPTX
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
PDF
Domain Modeling with FP (DDD Europe 2020)
Scott Wlaschin
 
PDF
Functional Design Patterns (DevTernity 2018)
Scott Wlaschin
 
PDF
Your code sucks, let's fix it
Rafael Dohms
 
PDF
Java 8 Workshop
Mario Fusco
 
PPTX
Optional in Java 8
Richard Walker
 
The Power of Composition (NDC Oslo 2020)
Scott Wlaschin
 
Railway Oriented Programming
Scott Wlaschin
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
Domain Modeling with FP (DDD Europe 2020)
Scott Wlaschin
 
Functional Design Patterns (DevTernity 2018)
Scott Wlaschin
 
Your code sucks, let's fix it
Rafael Dohms
 
Java 8 Workshop
Mario Fusco
 
Optional in Java 8
Richard Walker
 

What's hot (20)

PDF
Domain Modeling Made Functional (KanDDDinsky 2019)
Scott Wlaschin
 
PDF
Functional Programming Patterns (NDC London 2014)
Scott Wlaschin
 
PDF
PHP for Adults: Clean Code and Object Calisthenics
Guilherme Blanco
 
PDF
Pipeline oriented programming
Scott Wlaschin
 
PDF
F# for C# Programmers
Scott Wlaschin
 
PDF
Kotlin Coroutines in Practice @ KotlinConf 2018
Roman Elizarov
 
PPTX
Advanced JavaScript
Nascenia IT
 
PDF
NestJS
Wilson Su
 
PDF
The Power of Composition
Scott Wlaschin
 
PDF
Kotlin - Better Java
Dariusz Lorenc
 
PDF
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
 
PDF
The Functional Programmer's Toolkit (NDC London 2019)
Scott Wlaschin
 
PDF
Php Tutorials for Beginners
Vineet Kumar Saini
 
KEY
Object Calisthenics Applied to PHP
Guilherme Blanco
 
PPTX
Sharing Data Between Angular Components
Squash Apps Pvt Ltd
 
PDF
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
용근 권
 
PDF
Domain Driven Design Made Functional with Python
Jean Carlo Machado
 
PDF
A Prelude of Purity: Scaling Back ZIO
Jorge Vásquez
 
PDF
From framework coupled code to #microservices through #DDD /by @codelytv
CodelyTV
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Scott Wlaschin
 
Functional Programming Patterns (NDC London 2014)
Scott Wlaschin
 
PHP for Adults: Clean Code and Object Calisthenics
Guilherme Blanco
 
Pipeline oriented programming
Scott Wlaschin
 
F# for C# Programmers
Scott Wlaschin
 
Kotlin Coroutines in Practice @ KotlinConf 2018
Roman Elizarov
 
Advanced JavaScript
Nascenia IT
 
NestJS
Wilson Su
 
The Power of Composition
Scott Wlaschin
 
Kotlin - Better Java
Dariusz Lorenc
 
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
 
The Functional Programmer's Toolkit (NDC London 2019)
Scott Wlaschin
 
Php Tutorials for Beginners
Vineet Kumar Saini
 
Object Calisthenics Applied to PHP
Guilherme Blanco
 
Sharing Data Between Angular Components
Squash Apps Pvt Ltd
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
용근 권
 
Domain Driven Design Made Functional with Python
Jean Carlo Machado
 
A Prelude of Purity: Scaling Back ZIO
Jorge Vásquez
 
From framework coupled code to #microservices through #DDD /by @codelytv
CodelyTV
 
Ad

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

PDF
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Scott Wlaschin
 
PPTX
TechDaysNL 2015 - DDD with F#
Ronald Harmsen
 
PPTX
Mercury: A Functional Review
Mark Cheeseman
 
PPTX
FP Day 2011 - Turning to the Functional Side (using C# & F#)
Phillip Trelford
 
PPTX
F# for C# devs - SDD 2015
Phillip Trelford
 
PPT
Introduction to csharp
voegtu
 
PPT
Introduction to csharp
hmanjarawala
 
PPT
Introduction to csharp
voegtu
 
PPTX
Functional DDD
Alessandro Melchiori
 
PPT
Accessing loosely structured data from F# and C#
Tomas Petricek
 
PPTX
F# as our day job by 2016
Tomas Jansson
 
PDF
Software Developer Training
rungwiroon komalittipong
 
PPT
03 oo with-c-sharp
Naved khan
 
PDF
Functional programming with F#
Remik Koczapski
 
PDF
Domain Modeling Made Functional (DevTernity 2022)
Scott Wlaschin
 
PPTX
F# for C# devs - Leeds Sharp 2015
Phillip Trelford
 
PPTX
F# for C# devs - NDC Oslo 2015
Phillip Trelford
 
PDF
"Introduction to F#" - South Dakota Code Camp, November 5, 2011
Blend Interactive
 
PDF
1204csharp
g_hemanth17
 
PPTX
TechDaysNL 2015 - F# for C# Developers
Ronald Harmsen
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Scott Wlaschin
 
TechDaysNL 2015 - DDD with F#
Ronald Harmsen
 
Mercury: A Functional Review
Mark Cheeseman
 
FP Day 2011 - Turning to the Functional Side (using C# & F#)
Phillip Trelford
 
F# for C# devs - SDD 2015
Phillip Trelford
 
Introduction to csharp
voegtu
 
Introduction to csharp
hmanjarawala
 
Introduction to csharp
voegtu
 
Functional DDD
Alessandro Melchiori
 
Accessing loosely structured data from F# and C#
Tomas Petricek
 
F# as our day job by 2016
Tomas Jansson
 
Software Developer Training
rungwiroon komalittipong
 
03 oo with-c-sharp
Naved khan
 
Functional programming with F#
Remik Koczapski
 
Domain Modeling Made Functional (DevTernity 2022)
Scott Wlaschin
 
F# for C# devs - Leeds Sharp 2015
Phillip Trelford
 
F# for C# devs - NDC Oslo 2015
Phillip Trelford
 
"Introduction to F#" - South Dakota Code Camp, November 5, 2011
Blend Interactive
 
1204csharp
g_hemanth17
 
TechDaysNL 2015 - F# for C# Developers
Ronald Harmsen
 
Ad

More from Scott Wlaschin (17)

PDF
Building confidence in concurrent code with a model checker: TLA+ for program...
Scott Wlaschin
 
PDF
The lazy programmer's guide to writing thousands of tests
Scott Wlaschin
 
PDF
Reinventing the Transaction Script (NDC London 2020)
Scott Wlaschin
 
PDF
The Power Of Composition (DotNext 2019)
Scott Wlaschin
 
PDF
The Functional Programming Toolkit (NDC Oslo 2019)
Scott Wlaschin
 
PDF
Four Languages From Forty Years Ago (NewCrafts 2019)
Scott Wlaschin
 
PDF
Four Languages From Forty Years Ago
Scott Wlaschin
 
PDF
Designing with capabilities (DDD-EU 2017)
Scott Wlaschin
 
PDF
Thirteen ways of looking at a turtle
Scott Wlaschin
 
PDF
Designing with Capabilities
Scott Wlaschin
 
PDF
Dr Frankenfunctor and the Monadster
Scott Wlaschin
 
PDF
Enterprise Tic-Tac-Toe
Scott Wlaschin
 
PDF
An introduction to property based testing
Scott Wlaschin
 
PDF
Functional Programming Patterns (BuildStuff '14)
Scott Wlaschin
 
PDF
Swift vs. Language X
Scott Wlaschin
 
PDF
Doge-driven design
Scott Wlaschin
 
PDF
The Theory of Chains
Scott Wlaschin
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Scott Wlaschin
 
The lazy programmer's guide to writing thousands of tests
Scott Wlaschin
 
Reinventing the Transaction Script (NDC London 2020)
Scott Wlaschin
 
The Power Of Composition (DotNext 2019)
Scott Wlaschin
 
The Functional Programming Toolkit (NDC Oslo 2019)
Scott Wlaschin
 
Four Languages From Forty Years Ago (NewCrafts 2019)
Scott Wlaschin
 
Four Languages From Forty Years Ago
Scott Wlaschin
 
Designing with capabilities (DDD-EU 2017)
Scott Wlaschin
 
Thirteen ways of looking at a turtle
Scott Wlaschin
 
Designing with Capabilities
Scott Wlaschin
 
Dr Frankenfunctor and the Monadster
Scott Wlaschin
 
Enterprise Tic-Tac-Toe
Scott Wlaschin
 
An introduction to property based testing
Scott Wlaschin
 
Functional Programming Patterns (BuildStuff '14)
Scott Wlaschin
 
Swift vs. Language X
Scott Wlaschin
 
Doge-driven design
Scott Wlaschin
 
The Theory of Chains
Scott Wlaschin
 

Recently uploaded (20)

PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
PDF
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PDF
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PPTX
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
PDF
The Future of Artificial Intelligence (AI)
Mukul
 
PDF
Responsible AI and AI Ethics - By Sylvester Ebhonu
Sylvester Ebhonu
 
PDF
How-Cloud-Computing-Impacts-Businesses-in-2025-and-Beyond.pdf
Artjoker Software Development Company
 
PDF
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
PDF
REPORT: Heating appliances market in Poland 2024
SPIUG
 
PDF
CIFDAQ's Market Wrap : Bears Back in Control?
CIFDAQ
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PDF
Research-Fundamentals-and-Topic-Development.pdf
ayesha butalia
 
PPTX
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
PDF
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
PDF
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
PDF
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
PDF
Doc9.....................................
SofiaCollazos
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
The Future of Artificial Intelligence (AI)
Mukul
 
Responsible AI and AI Ethics - By Sylvester Ebhonu
Sylvester Ebhonu
 
How-Cloud-Computing-Impacts-Businesses-in-2025-and-Beyond.pdf
Artjoker Software Development Company
 
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
REPORT: Heating appliances market in Poland 2024
SPIUG
 
CIFDAQ's Market Wrap : Bears Back in Control?
CIFDAQ
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
Research-Fundamentals-and-Topic-Development.pdf
ayesha butalia
 
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
Doc9.....................................
SofiaCollazos
 

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
  • 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
  • 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  
  • 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
  • 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
  • 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 }
  • 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
  • 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