1
Thinking Functional inScala
Vikas HazratiKnoldus Software LLP
(c) 2014-15 Knoldus Software 2
agenda
● Introduction● Referential
Transparency● Substitution Model● Exception Handling
(c) 2014-15 Knoldus Software 3
agenda
● Introduction● Referential
Transparency● Substitution Model● Exception Handling
(c) 2014-15 Knoldus Software 4
impure
Scala is an impure functional programming language
(c) 2014-15 Knoldus Software 5
no side effects
Mutation
I/O
Exceptions
printing to consoleas well
(c) 2014-15 Knoldus Software 6
side-effect
If the function does something other than just providing result➔ Modifying a variable➔ Modifying a data structure in place➔ Setting a field on an object➔ Throwing an exception or halting with an error➔ Printing to the console or reading user input➔ Reading from or writing to a file➔ Drawing on the screen
(c) 2014-15 Knoldus Software 7
benefits of a pure function
Easy to
Test
Reuse
Parallelise
Generalize
Reason
(c) 2014-15 Knoldus Software 8
a pure function
● A function f with input type A and output type B (written in Scala as a single type: A => B , pronounced “ A to B ” or “ A arrow B ”) is a computation that relates every value a of type A to exactly one value b of type B such that b is determined solely by the value of a .
● Any changing state of an internal or external process is irrelevant to computing the result f(a)
● A function intToString having type Int => String will take every
integer to a corresponding string. Furthermore, if it really is a function, it will do nothing else
(c) 2014-15 Knoldus Software 9
a pure function
Referential Transparency
Substitution Model
Not contextdependent
(c) 2014-15 Knoldus Software 10
agenda
● Introduction● Referential
Transparency● Substitution Model● Exception Handling
(c) 2014-15 Knoldus Software 11
referential transparency
What is the difference between 2 code blocks?
(c) 2014-15 Knoldus Software 12
referential transparency
What is the difference between 2 code blocks?
If the expression can be replaced by its value and vice versa AND nothing changes then it is called Referential Transparency.
This model of substituting values for expressions is called Substitution Model.
(c) 2014-15 Knoldus Software 13
agenda
● Introduction● Referential
Transparency● Substitution Model● Exception Handling
(c) 2014-15 Knoldus Software 14
substitution model
What do you expect the output to be?
(c) 2014-15 Knoldus Software 15
substitution model
What do you expect the output to be?
(c) 2014-15 Knoldus Software 16
substitution model
Now, let us replace money2 with referntial transparency. Hence money2 becomes Money1.add(20)
Your sum1 is Money(60)Your sum2 is Money(90)
Why?
(c) 2014-15 Knoldus Software 17
substitution model
Ok, let us change the way Money works
What do you expect the output to be?
(c) 2014-15 Knoldus Software 18
substitution model
Ok, let us change the way Money works
What do you expect the output to be?
Your sum1 is GoodMoney(40)Your sum2 is GoodMoney(40)
(c) 2014-15 Knoldus Software 19
substitution model
And now lets apply the referential transparency
What do you expect the output to be?
(c) 2014-15 Knoldus Software 20
another example
(c) 2014-15 Knoldus Software 21
another example
Ideally we should be able to callany listIngredients with coffee
(c) 2014-15 Knoldus Software 22
side effect
What is the side effect here ?
(c) 2014-15 Knoldus Software 23
Functional Exception Handling
(c) 2014-15 Knoldus Software 24
Exceptions are not type safe
What is the datatype of this ?
How would the caller know that there is an exception which can occur?
How was it better in Java?
(c) 2014-15 Knoldus Software 25
Exception break RT
Exceptions introduce context dependence
What would be the output?
What would be the output once we introduce RT?
(c) 2014-15 Knoldus Software 26
Exception break RT
After introducing RT
What would be the output?
(c) 2014-15 Knoldus Software 27
How should we work with Exceptions?
(c) 2014-15 Knoldus Software 28
sentinel value
● Return a Sentinel value
Sentinel value
Silent error propagationBoilerplate codeTyped methods would not know valueDemands special handling at caller end
(c) 2014-15 Knoldus Software 29
other options?
Explicit return that function may not always have a value
What would you do?
(c) 2014-15 Knoldus Software 30
other options?
Explicit return that function may not always have a value
What would you do? Option
(c) 2014-15 Knoldus Software 31
option
When exception could be thrown, wrap the result in an Option
(c) 2014-15 Knoldus Software 32
wrapping exception throwing api's
● Lifting methods
f(A=>B)
def lift[A,B](f: A => B): Option[A] => Option[B] = _ map f
Example : val k = lift(math.abs)
(c) 2014-15 Knoldus Software 33
wrapping exception throwing api's
● Any number of parameters
(c) 2014-15 Knoldus Software 34
converting non option methods
(c) 2014-15 Knoldus Software 35
return exceptions
Sometimes we do want to tell the caller that an exception has occured and pass the exception
(c) 2014-15 Knoldus Software 36
return exceptions
Sometimes we do want to tell the caller that an exception has occured and pass the exception
Either
(c) 2014-15 Knoldus Software 37
Let us wrap our method
println(divideWithError(10,1).fold(a=>a,b=>b+1))
println(divideWithError(10,0).fold(a=>a,b=>b+1))
(c) 2014-15 Knoldus Software 38
That's It !
;)