Monoids,!Monoids everywhere
cyrille martraire!@cyriux
Can you tell the
difference?
This talk is the answer
A matter of Taste
http://rosshirt.blogspot.fr/
The Code Gourmet
(dedicated to @ziobrando)
Passionate developer
PARIS Since 1999
!@cyriux
Cyrille Martraire
Paris Software Craftsmanship Community
http://www.meetup.com/paris-software-craftsmanship/
WARNINGThe following show features no spectacular stunt, no live coding, only trivial Java code. You can re-create or re-enact at home with no danger.
Adopted 2005 Still in love
What do DDD & FP have in common?
"My first encounter with FP concepts was from DDD"
http://www.jaider.net/archives/609-intro-to-functional-programming/
PURE
So what do DDD & FP
have in common?
Value Objects................................................................................................. 19
Learn one
and get the other
one for FREE!
NICE STYLE
of code
Closure Associativity
Neutral Element
only 3 numbers in
programming
Monoid: encapsulate
diversity inside
0, 1, MANY
Neutral Element
Element
Operation
Encapsulate special cases
→ simple again
Battle against complexity
Applied often:
→ scalable process
→ can grow to high complexity
Scalable in complexity
For a given interface I find myself doing often 0, 1, Many
OO FTW!
0, 1, MANY
NullObject
Implementation(s)
Composite
Identity Element = NullObject
VatCalculation.NONE
Numbers int+int=int
(3+5)+2=3+(5+2) 0
Lists (.)+(.,.)=(.,.,.)
(a ︎)+(b,︎c)=(a ︎, b)+(c) ()
Strings "hello"+"world" "cy"+"ri"+"lle"
""
look simplistic; the key to very
complex behavior
The key to infinite scalability!
(space)
The key to infinite incremental computing!
(ti
me)
Abstractions in the small that
compose at large
Monoids: typical FP
FP: Everything is a
value
Therefore: Monoids are
values!
PROOF
Immutable Equals by value
Value Object
A DDD pattern to import FP-ish
values in OO languages
18 m + 16 m = 34 m
returns a new instance
Change -> new instance
SIDE-EFFECT -free
FUNCTIONS
Immutability &
Side-effect-free functions!
“Functional-First” style
90%“Functional-First” style
Value Objects
(Ok, gut feeling, I did’nt measure)
(25, EUR) +
(30, EUR) =
(55, EUR)
(25, EUR) +
(30, USD) =
exception
Money
amount currencyadd(Money): Money
<<ValueObject>>
Cashflows (Payments)
(25, EUR, today) +
(30, EUR, today) =
(55, EUR, today)
(25, EUR, today) +
(30, EUR, next day) =
exception
CashFlow
amount currency date
add(CashFlow):CashFlow
<<ValueObject>>
CLOSURE of
OPERATION
Cashflows Sequences
(10, EUR, 20/03)
(30, EUR, 21/03)
(25, EUR, 21/03)
(12, EUR, 22/03)
(10, EUR, 20/03)
(55, EUR, 21/03)
(12, EUR, 22/03)
+
=
Cashflow Sequence +
Cashflow Sequence =
Cashflow Sequence
Object Arithmetics
This is how domain experts THINK
about itSAY
SKETCH
[1, 3] Union* [2, 4]
= [1, 4]
* for a bounding box-kind definition of union
[1, 3] Union [2, 4]
= [1, 4] ][
Filter AND Filter
= Filter
Filter AND Filter
= Filter
Always
True
Filter OR
Filter =
Filter
Filter OR
Filter =
FilterAlways
False
Read, Write, Execute !
"most secure wins" !
r + w = r w + x = w
Configuration Maps
Color BLUE
Enable TrueTimeout 30 +
=
Color RED
Enable FalseTimeout 25
Desk FX
Color RED
Enable TrueTimeout 25
Desk FX
Default Desk-specific
Color BLUE
Enable TrueTimeout 30 +
=
Color RED
Enable FalseTimeout 25
Desk FX
Color RED
Enable TrueTimeout 25
Desk FX
Default Desk-specific
overw
rite
logic
al OR
min
Color BLUE
Enable TrueTimeout 30 +
=
Color RED
Enable FalseTimeout 25
Desk FX
Color RED
Enable TrueTimeout 25
Desk FX
Default Desk-specific
overw
rite
logic
al OR
min
Values are monoids too!
Color BLUE
Enable TrueTimeout 30 +
=Color BLUE
Enable TrueTimeout 30
Color NONE
Enable FalseTimeout +∞
Desk ALLNeutral Element
Color BLUE
Enable TrueTimeout 30 +
=Color BLUE
Enable TrueTimeout 30
Neutral Element
Color BLUE
Enable TrueTimeout 30 +
=Color BLUE
Enable TrueTimeout 30
Value Objects may be
*BIG* object trees!
(DOM)
Non-Linear Stuff (average, std dev,
K-clustering, barycenters...)
Average + Average = WRONG
Average + Average Not Composeable!
avg = sum / count !
avg = sum / count !
avg = sum / count !
avg = sum / count !
+
avg = sum / count !
avg = sum / count !
+ +
avg = sum / count !
avg = sum / count !
avg = sum / count
+
=
+
=
(sum, count) !
(sum, count) !
(sum, count)
+
=
Average
(sum, sum2, count) !
(sum, sum2, count) !
(sum, sum2, count)
+
=
Std deviation
Can model as a monoid even non-
linear stuff!
Monoid several times...
toString(): String union(MailingList): MailingList intersection(MailingList): MailingList nobody(): MailingList everybody(): MailingList
MailingList
average temperature! = t1.add(t2)! .scale(1/2)
returns a new instance
Change -> new instance
Space Vector
toCelsius(): Temperature toFarenheit(): Temperature add(Temperature): Temperature scale(double): Temperature
Temperature
Why is it useful?
(10, EUR, 20/03)
(30, EUR, 21/03)
(25, EUR, 21/03)
(12, EUR, 22/03)
(10, EUR, 20/03)
(55, EUR, 21/03)
(12, EUR, 22/03)
+
=
Cashflow Sequence +
Cashflow Sequence =
Cashflow Sequence
This is how domain experts THINK
about itSAY
SKETCH
DECLARATIVE STYLE
Much less code Much less bugs
// without monoids PaymentsFees(...) PaymentsFeesWithOptions(...) PaymentsFeesWithInsuranceAndOptions(...) PaymentsFeesWithInsurance(...) NoFeesButInsurance(...) ...
// with monoids fees(...) : Payments options(...) : Payments insurance(...) : Payments !Payments.add(Payments) : Payments
side-effect-free
operation
Very easy to test
input output
Much less stuff to learn
Cashflow Sequence +
Cashflow Sequence =
Cashflow Sequence
Monoid/Vector Spaces/Cyclic Group
Literature Documented
ESTABLISHED FORMALISMS
@annotations
@Monoid(neutral="emptyList") intersection(MailingList): MailingList !emptyList(): MailingList
MailingList
LIVING DOCUMENTATION
Write code that tells the business
domain stories
generic naming
@Monoid(neutral="emptyList") intersection(MailingList): MailingList !emptyList(): MailingList
MailingList
Domain-Specific naming
@Monoid(neutral="nobody") overlapping(MailingList): MailingList !nobody(): MailingList
MailingList
SELF-EXPLAINING VALUES
We Want:Traceability of processing
Just enrich our types
Just enrich our types
Just enrich our types
!
label field
Monad-ish No logging needed Each value stores
its history
http://stuartcook.files.wordpress.com/2010/11/happy-monkey.jpg
Composeability Composeability Composeability Composeability Composeability Composeability
Invest time: Learn DDD, and get
free FP exposure
A paradox: FP influence helps craft better Object-
Oriented code!
So simple, most people
have no appreciation
of that!
Monoids are good: Eat Them!
LOOK 4 Ur DOMAIN MONOIDZ!
Also learn other maths structures
Wikipedia is your friend!
http://wadler.blogspot.fr/2008/04/functional-programming-is-beautiful.html
Taste-Driven Development
TDD @cyriux
Questions? Did you try similar things too?
Let’s discuss!
@cyriux
Follow me @cyriux !
Slides: slideshare.net/cyriux Blog: cyrille.martraire.com
!
In Paris? Join !