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

Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersPiotr Paradziński
 
The Evolution of Scala
The Evolution of ScalaThe Evolution of Scala
The Evolution of ScalaMartin Odersky
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Transpilers Gone Wild: Introducing Hydra
Transpilers Gone Wild: Introducing HydraTranspilers Gone Wild: Introducing Hydra
Transpilers Gone Wild: Introducing HydraJoshua Shinavier
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!MeriamLachkar1
 
Lambda Expressions in Java
Lambda Expressions in JavaLambda Expressions in Java
Lambda Expressions in JavaErhan Bagdemir
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingDebasish Ghosh
 
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and ScalaSierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and ScalaPhilip Schwarz
 
An Introduction to Quill
An Introduction to QuillAn Introduction to Quill
An Introduction to QuillKnoldus Inc.
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaVladimir Kostyukov
 
Introduction to oop
Introduction to oopIntroduction to oop
Introduction to oopcolleges
 
Introduction to oop using java
Introduction  to oop using java Introduction  to oop using java
Introduction to oop using java omeed
 
java 8 new features
java 8 new features java 8 new features
java 8 new features Rohit Verma
 

What's hot (20)

Applicative Functor
Applicative FunctorApplicative Functor
Applicative Functor
 
Scala collection
Scala collectionScala collection
Scala collection
 
Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
 
The Evolution of Scala
The Evolution of ScalaThe Evolution of Scala
The Evolution of Scala
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Transpilers Gone Wild: Introducing Hydra
Transpilers Gone Wild: Introducing HydraTranspilers Gone Wild: Introducing Hydra
Transpilers Gone Wild: Introducing Hydra
 
Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
Java reflection
Java reflectionJava reflection
Java reflection
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
Lambda Expressions in Java
Lambda Expressions in JavaLambda Expressions in Java
Lambda Expressions in Java
 
Core java complete notes - Contact at +91-814-614-5674
Core java complete notes - Contact at +91-814-614-5674Core java complete notes - Contact at +91-814-614-5674
Core java complete notes - Contact at +91-814-614-5674
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
 
Function overloading
Function overloadingFunction overloading
Function overloading
 
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and ScalaSierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
An Introduction to Quill
An Introduction to QuillAn Introduction to Quill
An Introduction to Quill
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
Introduction to oop
Introduction to oopIntroduction to oop
Introduction to oop
 
Introduction to oop using java
Introduction  to oop using java Introduction  to oop using java
Introduction to oop using java
 
java 8 new features
java 8 new features java 8 new features
java 8 new features
 

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
 
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
 
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
 
Introducing scala
Introducing scalaIntroducing scala
Introducing 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

%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 

Recently uploaded (20)

%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 

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