The document discusses functional programming concepts including pure functions, immutable data, persistent data structures, algebraic data types, and function composition. It provides examples of implementing these concepts in Scala. It then discusses modeling domain state functionally by avoiding in-place mutation and combining state with time. Event sourcing, CQRS, and using a memory image with STM are proposed for managing state. Finally, some interesting links on functional programming topics are listed.
4. Functional Programming Gems
Immutable Data
Dataw/o shared mutable state
Theycan be shared freely... no locks, no semafores etc.
//Definitionofcaseobjects
sealedtraitProgrammingLanguageKind
caseobjectStaticextendsProgrammingLanguageKind
caseobjectDynamicextendsProgrammingLanguageKind
//Definitionofcaseclass
caseclassProgrammingLanguage(
name:String,
kind:ProgrammingLanguageKind
)
5. Functional Programming Gems
Persistent Data Structures
Always preserves the previous version of itself when itis
modified
Effectivelyimmutable with no in-place mutation
//Supposewehavealist...
vall1=List(1,2,3)
//Thenweaddaitemtoit
vall2=4::l
assert(l1!=l2)//yieldstrue
6. Functional Programming Gems
Algebraic Data Types, take one
An algebraic datatype is akind of composite type, i.e. atype
formed bycombiningother types
Datatypes with some algebra, i.e. structure and operations
Unit type, Sumtypeand Product type
e.g. Lists can byformalydescribed as L = I + X * L
valemptyList=List()//Unittype
valsimpleList=1::emptyList//Sumtype
valproductList=2::emptyList//Producttype
7. Functional Programming Gems
Algebraic Data Types, take two
Domain entities are represented usingproduct types
caseclasses are bestfitin Scala
//Tupleissimplestproducttype
valprogrammingLanguage=(name,kind)
//Producttypeviacaseclass
caseclassProgrammingLanguage(
name:String,
kind:ProgrammingLanguageKind
)
8. Functional Programming Gems
Algebraic Data Types, take three
Domain values and enums are represented usingsumtypes
Inheritance and sealed traits/classes are bestfitin Scala
//Exampleofsum-type,OptionfromScalalibrary(codesimplified)
sealedabstractclassOption[+A]
finalcaseclassSome[+A](x:A)extendsOption[A]
caseobjectNoneextendsOption[Nothing]
//Sumtypeviacaseobjects
sealedtraitProgrammingLanguageKind
caseobjectStaticextendsProgrammingLanguageKind
caseobjectDynamicextendsProgrammingLanguageKind
9. Functional Programming Gems
Function Composition
Functions compose when theycause no side-effects
Side-effects do notcompose
scala>deffoo(something:String):String=s"foo($something)"
scala>defbar(something:String):String=s"bar($something)"
valcomposit=foo_composebar_
valreverseComposit=foo_andThenbar_
composit("anything")
>foo(bar(anything))
reverseComposit("anything")
>bar(foo(anything))
10. Functional Programming Gems
Combinators
Applyhigh-order functions
Glue for chainingfunctions
Pure functions as domain invariants and behavior
foundmap{foundLine=>partitions.success}
| |
Combinator High-orderfn
Monadicchaining,viafor-comprehensions
for{ |
_<-quantityInvariant(quantity)
_<-priceInvariant(price)
(found,rest)<-productAlreadyExists(productId)
}yield{/*dosomething*/}
11. Functional Programming Gems
Side Effects
FP languages encourage isolatingside-effects from pure
domain logic
Known side-effects (notinsignigicant)
1. DBaccess
2. Logging
3. IO operations
Example
result.foreach{case(order,event)=>
orderRepository.saveOrUpdate(order)
}
14. Perception of State
Domain state is effecivelymutable
Can retain previous states
Historyof whathappened
In-place mutation are wrongfor domain model
Theycombine state with time