SlideShare a Scribd company logo
1 of 88
Download to read offline
Power of Functions
in a Typed World
- A JVM Perspective
Debasish Ghosh (dghosh@acm.org)
@debasishg
functions as the primary abstraction of design
pure functions as the primary abstraction of
design
statically typed pure functions as the primary
abstraction of design
def foo[A, B](arg: A): B
Motivation
• Explore if we can consider functions as the primary abstraction
of design
• Function composition to build larger behaviors out of smaller
ones
• How referential transparency helps composition and local
reasoning
• Types as the substrate (algebra) of composition
Types
Functions (Mapping between types)
(Algebraic)
• sum type
• product type
• ADTs
• compose
• based on algebra of types
Modules (Grouping related functions) • compose
• can be parameterized
Application (Top level artifact)
Functional Programming
Programming with
Functions
f
A B
def plus2(arg: Int): Int = arg + 2
def size(n: Int): Int = 1000 / n
def size(n: Int): Option[Int] =
if (n == 0) None else Some(1000 / n)
Pure Value
Functional Programming
• Programming with pure functions
• Output determined completely by the input
• No side-effects
• Referentially transparent
Referential Transparency
Referential Transparency
• An expression is said to be referentially transparent if it
can be replaced with its value without changing the behavior
of a program
• The value of an expression depends only on the values of its
constituent expressions (if any) and these subexpressions
may be replaced freely by others possessing the same
value
Referential Transparency
expression oriented
programming
substitution model
of evaluation
• An expression is said to be referentially transparent if it
can be replaced with its value without changing the behavior
of a program
• The value of an expression depends only on the values of its
constituent expressions (if any) and these subexpressions
may be replaced freely by others possessing the same
value
scala> val str = "Hello".reverse
str: String = olleH
scala> (str, str)
res0: (String, String) = (olleH,olleH)
scala> ("Hello".reverse, "Hello".reverse)
res1: (String, String) = (olleH,olleH)
scala> def foo(iter: Iterator[Int]) = iter.next + 2
foo: (iter: Iterator[Int])Int
scala> (1 to 20).iterator
res0: Iterator[Int] = non-empty iterator
scala> val a = foo(res0)
a: Int = 3
scala> (a, a)
res1: (Int, Int) = (3,3)
scala> (1 to 20).iterator
res3: Iterator[Int] = non-empty iterator
scala> (foo(res3), foo(res3))
res4: (Int, Int) = (3,4)
def foo(i: Iterator[Int]): Int = {
val a = i.next
val b = a + 1
a + b
}
scala> val i = (1 to 20).iterator
i: Iterator[Int] = non-empty iterator
scala> foo(i)
res8: Int = 3
scala> val i = (1 to 20).iterator
i: Iterator[Int] = non-empty iterator
scala> i.next + i.next + 1
res9: Int = 4
• non compositional
• hinders local understanding
• breaks RT
Referential Transparency enables
Local Reasoning
and Function Composition
Types
What is meant by the
algebra of a type ?
•Nothing
•Unit
•Boolean
•Byte
•String
What is meant by the
algebra of a type ?
•Nothing -> 0
•Unit -> 1
•Boolean -> 2
•Byte -> 256
•String -> a lot
What is meant by the
algebra of a type ?
•(Boolean, Unit)
•(Byte, Unit)
•(Byte, Boolean)
•(Byte, Byte)
•(String, String)
What is meant by the
algebra of a type ?
•(Boolean, Unit) -> 2x1 = 2
•(Byte, Unit) -> 256x1 = 256
•(Byte, Boolean) -> 256x2 = 512
•(Byte, Byte) -> 256x256 = 65536
•(String, String) -> a lot
What is meant by the
algebra of a type ?
• Quiz: Generically, how many inhabitants can we
have for a type (a, b)?
• Answer: 1 inhabitant for each combination of
a’s and b’s (a x b)
Product Types
• Ordered pairs of values one from each type in
the order specified - this and that
• Can be generalized to a finite product indexed by
a finite set of indices
Product Types in Scala
type Point = (Int, Int)
val p = (10, 12)
case class Account(no: String,
name: String,
address: String,
dateOfOpening: Date,
dateOfClosing: Option[Date]
)
What is meant by the
algebra of a type ?
•Boolean or Unit
•Byte or Unit
•Byte or Boolean
•Byte or Byte
•String or String
What is meant by the
algebra of a type ?
•Boolean or Unit -> 2+1 = 3
•Byte or Unit -> 256+1 = 257
•Byte or Boolean -> 256+2 = 258
•Byte or Byte -> 256+256 = 512
•String or String -> a lot
Sum Types
• Model data structures involving alternatives -
this or that
• A tree can have a leaf or an internal node which,
is again a tree
• In Scala, a sum type is usually referred to as an
Algebraic DataType (ADT)
Sum Types in Scala
sealed trait Shape
case class Circle(origin: Point,
radius: BigDecimal) extends Shape
case class Rectangle(diag_1: Point,
diag_2: Point) extends Shape
Sum Types are
Expressive
• Booleans - true or false
• Enumerations - sum types may be used to define finite
enumeration types, whose values are one of an explicitly
specified finite set
• Optionality - the Option data type in Scala is encoded using a
sum type
• Disjunction - this or that, the Either data type in Scala
• Failure encoding - the Try data type in Scala to indicate that
the computation may raise an exception
sealed trait InstrumentType
case object CCY extends InstrumentType
case object EQ extends InstrumentType
case object FI extends InstrumentType
sealed trait Instrument {
def instrumentType: InstrumentType
}
case class Equity(isin: String, name: String, issueDate: Date,
faceValue: Amount) extends Instrument {
final val instrumentType = EQ
}
case class FixedIncome(isin: String, name: String, issueDate: Date,
maturityDate: Option[Date], nominal: Amount) extends Instrument {
final val instrumentType = FI
}
case class Currency(isin: String) extends Instrument {
final val instrumentType = CCY
}
De-structuring with
Pattern Matching
def process(i: Instrument) = i match {
case Equity(isin, _, _, faceValue) => // ..
case FixedIncome(isin, _, issueDate, _, nominal) => // ..
case Currency(isin) => // ..
}
Exhaustiveness Check
Types
Algebra of Types
def f: A => B = // ..
def g: B => C = // ..
Algebraic Composition of
Types
def f: A => B = // ..
def g: B => C = // ..
def h: A => C = g compose f
scala> case class Employee(id: String, name: String, age: Int)
defined class Employee
scala> def getEmployee: String => Employee = id => Employee("a", "abc")
getEmployee: String => Employee
scala> def getSalary: Employee => BigDecimal = e => BigDecimal(100)
getSalary: Employee => BigDecimal
scala> def computeTax: BigDecimal => BigDecimal = s => 0.3 * s
computeTax: BigDecimal => BigDecimal
scala> getEmployee andThen getSalary andThen computeTax
res3: String => BigDecimal = scala.Function1$$Lambda$1306/913564177@4ac77269
scala> res3("emp-100")
res4: BigDecimal = 30.0
Function Composition
• Functions compose when types align
• And we get larger functions
• Still values - composition IS NOT execution (composed
function is still a value)
• Pure and referentially transparent
Function Composition
f:A => B
g:B => C
(f
andThen
g):A
=>
C
id[A]:A => A id[B]:B => B
(Slide adapted from a presentation by Rob Norris at Scale by the Bay 2017)
Functions are first class
scala> List(1, 2, 3).map(e => e * 2)
res0: List[Int] = List(2, 4, 6)
scala> (1 to 10).filter(e => e % 2 == 0)
res2: s.c.i.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
scala> def even(i: Int) = i % 2 == 0
even: (i: Int)Boolean
scala> (1 to 10).filter(even)
res3: s.c.i.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
scala> (1 to 10).foldLeft(0)((a, e) => a + e)
res4: Int = 55
Programming with Values
def size(n: Int): Option[Int] =
if (n == 0) None else Some(1000 / n)
Pure Value
def size(n: Int): Either[String,Int] =
if (n == 0) Left(“Division by zero”)
else Right(1000 / n)
Pure Value
def size(n: Int): Either[String,Int] =
if (n == 0) Left(“Division by zero”)
else Right(1000 / n)
Sum Type
Error Path
Happy Path
Types don’t lie
unless you try and subvert your type system
some languages like Haskell make subversion
difficult
Types Functionsmapping between types
closed under composition
(algebraic)
(referentially transparent)
Does this approach scale ?
Types
Functions (Mapping between types)
(Algebraic)
• sum type
• product type
• ADTs
• compose
• based on algebra of types
Modules (Grouping related functions) • compose
• can be parameterized
Application (Top level artifact)
trait Combiner[A] {
def zero: A
def combine(l: A, r: => A): A
}
//identity
combine(x, zero) =
combine(zero, x) = x
// associativity
combine(x, combine(y, z)) =
combine(combine(x, y), z)
Module with an algebra
trait Monoid[A] {
def zero: A
def combine(l: A, r: => A): A
}
//identity
combine(x, zero) =
combine(zero, x) = x
// associativity
combine(x, combine(y, z)) =
combine(combine(x, y), z)
Module with an Algebra
trait Foldable[F[_]] {
def foldl[A, B](as: F[A], z: B, f: (B, A) => B): B
def foldMap[A, B](as: F[A], f: A => B)
(implicit m: Monoid[B]): B =
foldl(as,
m.zero,
(b: B, a: A) => m.combine(b, f(a))
)
}
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
https://stackoverflow.com/a/4765918
case class Sum(value: Int)
case class Product(value: Int)
implicit val sumMonoid = new Monoid[Sum] {
def zero = Sum(0)
def add(a: Sum, b: Sum) = Sum(a.value + b.value)
}
implicit val productMonoid = new Monoid[Product] {
def zero = Product(1)
def add(a: Product, b: Product) =
Product(a.value * b.value)
}
val sumOf123 = mapReduce(List(1,2,3), Sum)
val productOf456 = mapReduce(List(4,5,6), Product)
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
combinator
(higher order function)
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
Type constructor
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
F needs to honor the
algebra of a Foldable
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
B needs to honor the
algebra of a Monoid
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
combinator
(higher order function)
Type constructor
F needs to honor the
algebra of a Foldable
B needs to honor the
algebra of a Monoid
Types
Functions (Mapping between types)
(Algebraic)
• sum type
• product type
• ADTs
• compose
• based on algebra of types
Modules (Grouping related functions) • compose
• can be parameterized
Application (Top level artifact)
Types and Functions to drive our
design instead of classes as in OO
Client places order
- flexible format
1
Client places order
- flexible format
Transform to internal domain
model entity and place for execution
1 2
Client places order
- flexible format
Transform to internal domain
model entity and place for execution
Trade & Allocate to
client accounts
1 2
3
def clientOrders:
List[ClientOrder] => List[Order]
def clientOrders:
List[ClientOrder] => Either[Error,
List[Order]]
def clientOrders:
List[ClientOrder] => Either[Error, List[Order]]
def execute(market: Market, brokerAccount: Account):
List[Order] => Either[Error, List[Execution]]
def allocate(accounts: List[Account]):
List[Execution] => Either[Error, List[Trade]]
Function Composition
f:A => B
g:B => C
(f
andThen
g):A
=>
C
id[A]:A => A id[B]:B => B
(Slide adapted from a presentation by Rob Norris at Scale by the Bay 2017)
def clientOrders:
List[ClientOrder] => Either[Error, List[Order]]
def execute(market: Market, brokerAccount: Account):
List[Order] => Either[Error, List[Execution]]
def allocate(accounts: List[Account]):
List[Execution] => Either[Error, List[Trade]]
Plain function composition doesn’t work here
We have those pesky Either[Error, ..]
floating around
Effects
Effectful function composition
Effectful Function
Composition
f:A => F[B]
g:B => F[C]
(f
andThen
g):A
=>
F[C]
pure[A]:A => F[A] pure[B]:B => F[B]
(Slide adapted from a presentation by Rob Norris at Scale by the Bay 2017)
Effectful Function
Composition
final case class Kleisli[F[_], A, B](run: A => F[B]) {
def andThen[C](f: B => F[C])
: Kleisli[F, A, C] = // ..
}
type ErrorOr[A] = Either[Error, A]
def clientOrders:
Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]]
def execute(market: Market, brokerAccount: Account):
Kleisli[ErrorOr, List[Order], List[Execution]]
def allocate(accounts: List[Account]):
Kleisli[ErrorOr, List[Execution], List[Trade]]
def tradeGeneration(
market: Market,
broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
type ErrorOr[A] = Either[Error, A]
def clientOrders:
Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]]
def execute(market: Market, brokerAccount: Account):
Kleisli[ErrorOr, List[Order], List[Execution]]
def allocate(accounts: List[Account]):
Kleisli[ErrorOr, List[Execution], List[Trade]]
def tradeGeneration(market: Market, broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
type ErrorOr[A] = Either[Error, A]
def clientOrders:
Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]]
def execute(market: Market, brokerAccount: Account):
Kleisli[ErrorOr, List[Order], List[Execution]]
def allocate(accounts: List[Account]):
Kleisli[ErrorOr, List[Execution], List[Trade]]
def tradeGeneration(market: Market, broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
trait TradingService {
}
type ErrorOr[A] = Either[Error, A]
def clientOrders:
Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]]
def execute(market: Market, brokerAccount: Account):
Kleisli[ErrorOr, List[Order], List[Execution]]
def allocate(accounts: List[Account]):
Kleisli[ErrorOr, List[Execution], List[Trade]]
def tradeGeneration(market: Market, broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
trait TradingService {
}
trait TradingApplication extends TradingService
with ReferenceDataService
with ReportingService
with AuditingService {
// ..
}
object TradingApplication extends TradingApplication
Modules Compose
https://github.com/debasishg/fp-fnconf-2018
Thanks!

More Related Content

What's hot

ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Jean Carlo Machado
 
Python tools to deploy your machine learning models faster
Python tools to deploy your machine learning models fasterPython tools to deploy your machine learning models faster
Python tools to deploy your machine learning models fasterJeff Hale
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Scott Wlaschin
 
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
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
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
 
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaExploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaJorge Vásquez
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
Designing with malli
Designing with malliDesigning with malli
Designing with malliMetosin Oy
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Philip Schwarz
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門Hideyuki Tanaka
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick SmackdownAlexander Ioffe
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with CapabilitiesScott Wlaschin
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 

What's hot (20)

ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python
 
Python tools to deploy your machine learning models faster
Python tools to deploy your machine learning models fasterPython tools to deploy your machine learning models faster
Python tools to deploy your machine learning models faster
 
Dystopian fiction
Dystopian fictionDystopian fiction
Dystopian fiction
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)
 
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
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
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
 
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaExploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in Scala
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Designing with malli
Designing with malliDesigning with malli
Designing with malli
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with Capabilities
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 

Similar to Power of functions in a typed world

Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Monads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevMonads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevJavaDayUA
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional PatternsDebasish Ghosh
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsVasil Remeniuk
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingDebasish Ghosh
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellMichel Rijnders
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsPhilip Schwarz
 
Scala or functional programming from a python developer's perspective
Scala or functional programming from a python developer's perspectiveScala or functional programming from a python developer's perspective
Scala or functional programming from a python developer's perspectivegabalese
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverseLuka Jacobowitz
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009David Pollak
 
Comparing Haskell & Scala
Comparing Haskell & ScalaComparing Haskell & Scala
Comparing Haskell & ScalaMartin Ockajak
 

Similar to Power of functions in a typed world (20)

Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Monads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevMonads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy Dyagilev
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
Scala or functional programming from a python developer's perspective
Scala or functional programming from a python developer's perspectiveScala or functional programming from a python developer's perspective
Scala or functional programming from a python developer's perspective
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
Array
ArrayArray
Array
 
Comparing Haskell & Scala
Comparing Haskell & ScalaComparing Haskell & Scala
Comparing Haskell & Scala
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 

More from Debasish Ghosh

Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsDebasish Ghosh
 
Architectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain ModelsArchitectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain ModelsDebasish Ghosh
 
An Algebraic Approach to Functional Domain Modeling
An Algebraic Approach to Functional Domain ModelingAn Algebraic Approach to Functional Domain Modeling
An Algebraic Approach to Functional Domain ModelingDebasish Ghosh
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingDebasish Ghosh
 
From functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingFrom functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingDebasish Ghosh
 
Domain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDomain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDebasish Ghosh
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesDebasish Ghosh
 
Big Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageBig Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageDebasish Ghosh
 
Functional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modelingFunctional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modelingDebasish Ghosh
 
DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDebasish Ghosh
 
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDebasish Ghosh
 

More from Debasish Ghosh (11)

Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming Applications
 
Architectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain ModelsArchitectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain Models
 
An Algebraic Approach to Functional Domain Modeling
An Algebraic Approach to Functional Domain ModelingAn Algebraic Approach to Functional Domain Modeling
An Algebraic Approach to Functional Domain Modeling
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
 
From functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingFrom functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modeling
 
Domain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDomain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approach
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
Big Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageBig Data - architectural concerns for the new age
Big Data - architectural concerns for the new age
 
Functional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modelingFunctional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modeling
 
DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic model
 
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
 

Recently uploaded

why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 

Recently uploaded (20)

why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 

Power of functions in a typed world

  • 1. Power of Functions in a Typed World - A JVM Perspective Debasish Ghosh (dghosh@acm.org) @debasishg
  • 2. functions as the primary abstraction of design
  • 3. pure functions as the primary abstraction of design
  • 4. statically typed pure functions as the primary abstraction of design def foo[A, B](arg: A): B
  • 5. Motivation • Explore if we can consider functions as the primary abstraction of design • Function composition to build larger behaviors out of smaller ones • How referential transparency helps composition and local reasoning • Types as the substrate (algebra) of composition
  • 6. Types Functions (Mapping between types) (Algebraic) • sum type • product type • ADTs • compose • based on algebra of types Modules (Grouping related functions) • compose • can be parameterized Application (Top level artifact)
  • 9. def plus2(arg: Int): Int = arg + 2
  • 10. def size(n: Int): Int = 1000 / n
  • 11. def size(n: Int): Option[Int] = if (n == 0) None else Some(1000 / n) Pure Value
  • 12. Functional Programming • Programming with pure functions • Output determined completely by the input • No side-effects • Referentially transparent
  • 14. Referential Transparency • An expression is said to be referentially transparent if it can be replaced with its value without changing the behavior of a program • The value of an expression depends only on the values of its constituent expressions (if any) and these subexpressions may be replaced freely by others possessing the same value
  • 15. Referential Transparency expression oriented programming substitution model of evaluation • An expression is said to be referentially transparent if it can be replaced with its value without changing the behavior of a program • The value of an expression depends only on the values of its constituent expressions (if any) and these subexpressions may be replaced freely by others possessing the same value
  • 16. scala> val str = "Hello".reverse str: String = olleH scala> (str, str) res0: (String, String) = (olleH,olleH) scala> ("Hello".reverse, "Hello".reverse) res1: (String, String) = (olleH,olleH)
  • 17. scala> def foo(iter: Iterator[Int]) = iter.next + 2 foo: (iter: Iterator[Int])Int scala> (1 to 20).iterator res0: Iterator[Int] = non-empty iterator scala> val a = foo(res0) a: Int = 3 scala> (a, a) res1: (Int, Int) = (3,3) scala> (1 to 20).iterator res3: Iterator[Int] = non-empty iterator scala> (foo(res3), foo(res3)) res4: (Int, Int) = (3,4)
  • 18. def foo(i: Iterator[Int]): Int = { val a = i.next val b = a + 1 a + b } scala> val i = (1 to 20).iterator i: Iterator[Int] = non-empty iterator scala> foo(i) res8: Int = 3 scala> val i = (1 to 20).iterator i: Iterator[Int] = non-empty iterator scala> i.next + i.next + 1 res9: Int = 4 • non compositional • hinders local understanding • breaks RT
  • 21. Types
  • 22. What is meant by the algebra of a type ? •Nothing •Unit •Boolean •Byte •String
  • 23. What is meant by the algebra of a type ? •Nothing -> 0 •Unit -> 1 •Boolean -> 2 •Byte -> 256 •String -> a lot
  • 24. What is meant by the algebra of a type ? •(Boolean, Unit) •(Byte, Unit) •(Byte, Boolean) •(Byte, Byte) •(String, String)
  • 25. What is meant by the algebra of a type ? •(Boolean, Unit) -> 2x1 = 2 •(Byte, Unit) -> 256x1 = 256 •(Byte, Boolean) -> 256x2 = 512 •(Byte, Byte) -> 256x256 = 65536 •(String, String) -> a lot
  • 26. What is meant by the algebra of a type ? • Quiz: Generically, how many inhabitants can we have for a type (a, b)? • Answer: 1 inhabitant for each combination of a’s and b’s (a x b)
  • 27. Product Types • Ordered pairs of values one from each type in the order specified - this and that • Can be generalized to a finite product indexed by a finite set of indices
  • 28. Product Types in Scala type Point = (Int, Int) val p = (10, 12) case class Account(no: String, name: String, address: String, dateOfOpening: Date, dateOfClosing: Option[Date] )
  • 29. What is meant by the algebra of a type ? •Boolean or Unit •Byte or Unit •Byte or Boolean •Byte or Byte •String or String
  • 30. What is meant by the algebra of a type ? •Boolean or Unit -> 2+1 = 3 •Byte or Unit -> 256+1 = 257 •Byte or Boolean -> 256+2 = 258 •Byte or Byte -> 256+256 = 512 •String or String -> a lot
  • 31. Sum Types • Model data structures involving alternatives - this or that • A tree can have a leaf or an internal node which, is again a tree • In Scala, a sum type is usually referred to as an Algebraic DataType (ADT)
  • 32. Sum Types in Scala sealed trait Shape case class Circle(origin: Point, radius: BigDecimal) extends Shape case class Rectangle(diag_1: Point, diag_2: Point) extends Shape
  • 33. Sum Types are Expressive • Booleans - true or false • Enumerations - sum types may be used to define finite enumeration types, whose values are one of an explicitly specified finite set • Optionality - the Option data type in Scala is encoded using a sum type • Disjunction - this or that, the Either data type in Scala • Failure encoding - the Try data type in Scala to indicate that the computation may raise an exception
  • 34. sealed trait InstrumentType case object CCY extends InstrumentType case object EQ extends InstrumentType case object FI extends InstrumentType sealed trait Instrument { def instrumentType: InstrumentType } case class Equity(isin: String, name: String, issueDate: Date, faceValue: Amount) extends Instrument { final val instrumentType = EQ } case class FixedIncome(isin: String, name: String, issueDate: Date, maturityDate: Option[Date], nominal: Amount) extends Instrument { final val instrumentType = FI } case class Currency(isin: String) extends Instrument { final val instrumentType = CCY }
  • 35. De-structuring with Pattern Matching def process(i: Instrument) = i match { case Equity(isin, _, _, faceValue) => // .. case FixedIncome(isin, _, issueDate, _, nominal) => // .. case Currency(isin) => // .. }
  • 37. Types
  • 38. Algebra of Types def f: A => B = // .. def g: B => C = // ..
  • 39. Algebraic Composition of Types def f: A => B = // .. def g: B => C = // .. def h: A => C = g compose f
  • 40. scala> case class Employee(id: String, name: String, age: Int) defined class Employee scala> def getEmployee: String => Employee = id => Employee("a", "abc") getEmployee: String => Employee scala> def getSalary: Employee => BigDecimal = e => BigDecimal(100) getSalary: Employee => BigDecimal scala> def computeTax: BigDecimal => BigDecimal = s => 0.3 * s computeTax: BigDecimal => BigDecimal scala> getEmployee andThen getSalary andThen computeTax res3: String => BigDecimal = scala.Function1$$Lambda$1306/913564177@4ac77269 scala> res3("emp-100") res4: BigDecimal = 30.0
  • 41. Function Composition • Functions compose when types align • And we get larger functions • Still values - composition IS NOT execution (composed function is still a value) • Pure and referentially transparent
  • 42. Function Composition f:A => B g:B => C (f andThen g):A => C id[A]:A => A id[B]:B => B (Slide adapted from a presentation by Rob Norris at Scale by the Bay 2017)
  • 44. scala> List(1, 2, 3).map(e => e * 2) res0: List[Int] = List(2, 4, 6) scala> (1 to 10).filter(e => e % 2 == 0) res2: s.c.i.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
  • 45. scala> def even(i: Int) = i % 2 == 0 even: (i: Int)Boolean scala> (1 to 10).filter(even) res3: s.c.i.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10) scala> (1 to 10).foldLeft(0)((a, e) => a + e) res4: Int = 55
  • 47. def size(n: Int): Option[Int] = if (n == 0) None else Some(1000 / n) Pure Value
  • 48. def size(n: Int): Either[String,Int] = if (n == 0) Left(“Division by zero”) else Right(1000 / n) Pure Value
  • 49. def size(n: Int): Either[String,Int] = if (n == 0) Left(“Division by zero”) else Right(1000 / n) Sum Type Error Path Happy Path
  • 50. Types don’t lie unless you try and subvert your type system some languages like Haskell make subversion difficult
  • 51. Types Functionsmapping between types closed under composition (algebraic) (referentially transparent)
  • 53. Types Functions (Mapping between types) (Algebraic) • sum type • product type • ADTs • compose • based on algebra of types Modules (Grouping related functions) • compose • can be parameterized Application (Top level artifact)
  • 54. trait Combiner[A] { def zero: A def combine(l: A, r: => A): A } //identity combine(x, zero) = combine(zero, x) = x // associativity combine(x, combine(y, z)) = combine(combine(x, y), z)
  • 55. Module with an algebra trait Monoid[A] { def zero: A def combine(l: A, r: => A): A } //identity combine(x, zero) = combine(zero, x) = x // associativity combine(x, combine(y, z)) = combine(combine(x, y), z)
  • 56. Module with an Algebra trait Foldable[F[_]] { def foldl[A, B](as: F[A], z: B, f: (B, A) => B): B def foldMap[A, B](as: F[A], f: A => B) (implicit m: Monoid[B]): B = foldl(as, m.zero, (b: B, a: A) => m.combine(b, f(a)) ) }
  • 57. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) https://stackoverflow.com/a/4765918
  • 58. case class Sum(value: Int) case class Product(value: Int) implicit val sumMonoid = new Monoid[Sum] { def zero = Sum(0) def add(a: Sum, b: Sum) = Sum(a.value + b.value) } implicit val productMonoid = new Monoid[Product] { def zero = Product(1) def add(a: Product, b: Product) = Product(a.value * b.value) }
  • 59. val sumOf123 = mapReduce(List(1,2,3), Sum) val productOf456 = mapReduce(List(4,5,6), Product)
  • 60. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f)
  • 61. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) combinator (higher order function)
  • 62. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) Type constructor
  • 63. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) F needs to honor the algebra of a Foldable
  • 64. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) B needs to honor the algebra of a Monoid
  • 65. def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) combinator (higher order function) Type constructor F needs to honor the algebra of a Foldable B needs to honor the algebra of a Monoid
  • 66. Types Functions (Mapping between types) (Algebraic) • sum type • product type • ADTs • compose • based on algebra of types Modules (Grouping related functions) • compose • can be parameterized Application (Top level artifact)
  • 67. Types and Functions to drive our design instead of classes as in OO
  • 68. Client places order - flexible format 1
  • 69. Client places order - flexible format Transform to internal domain model entity and place for execution 1 2
  • 70. Client places order - flexible format Transform to internal domain model entity and place for execution Trade & Allocate to client accounts 1 2 3
  • 72. def clientOrders: List[ClientOrder] => Either[Error, List[Order]]
  • 73. def clientOrders: List[ClientOrder] => Either[Error, List[Order]] def execute(market: Market, brokerAccount: Account): List[Order] => Either[Error, List[Execution]] def allocate(accounts: List[Account]): List[Execution] => Either[Error, List[Trade]]
  • 74. Function Composition f:A => B g:B => C (f andThen g):A => C id[A]:A => A id[B]:B => B (Slide adapted from a presentation by Rob Norris at Scale by the Bay 2017)
  • 75. def clientOrders: List[ClientOrder] => Either[Error, List[Order]] def execute(market: Market, brokerAccount: Account): List[Order] => Either[Error, List[Execution]] def allocate(accounts: List[Account]): List[Execution] => Either[Error, List[Trade]]
  • 76. Plain function composition doesn’t work here
  • 77. We have those pesky Either[Error, ..] floating around
  • 80. Effectful Function Composition f:A => F[B] g:B => F[C] (f andThen g):A => F[C] pure[A]:A => F[A] pure[B]:B => F[B] (Slide adapted from a presentation by Rob Norris at Scale by the Bay 2017)
  • 81. Effectful Function Composition final case class Kleisli[F[_], A, B](run: A => F[B]) { def andThen[C](f: B => F[C]) : Kleisli[F, A, C] = // .. }
  • 82. type ErrorOr[A] = Either[Error, A] def clientOrders: Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]] def execute(market: Market, brokerAccount: Account): Kleisli[ErrorOr, List[Order], List[Execution]] def allocate(accounts: List[Account]): Kleisli[ErrorOr, List[Execution], List[Trade]]
  • 83. def tradeGeneration( market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) }
  • 84. type ErrorOr[A] = Either[Error, A] def clientOrders: Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]] def execute(market: Market, brokerAccount: Account): Kleisli[ErrorOr, List[Order], List[Execution]] def allocate(accounts: List[Account]): Kleisli[ErrorOr, List[Execution], List[Trade]] def tradeGeneration(market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) }
  • 85. type ErrorOr[A] = Either[Error, A] def clientOrders: Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]] def execute(market: Market, brokerAccount: Account): Kleisli[ErrorOr, List[Order], List[Execution]] def allocate(accounts: List[Account]): Kleisli[ErrorOr, List[Execution], List[Trade]] def tradeGeneration(market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) } trait TradingService { }
  • 86. type ErrorOr[A] = Either[Error, A] def clientOrders: Kleisli[ErrorOr, List[ClientOrder], List[ClientOrder]] def execute(market: Market, brokerAccount: Account): Kleisli[ErrorOr, List[Order], List[Execution]] def allocate(accounts: List[Account]): Kleisli[ErrorOr, List[Execution], List[Trade]] def tradeGeneration(market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) } trait TradingService { }
  • 87. trait TradingApplication extends TradingService with ReferenceDataService with ReportingService with AuditingService { // .. } object TradingApplication extends TradingApplication Modules Compose https://github.com/debasishg/fp-fnconf-2018