Tutorials Hut




  •  Scala functions, closure, Pure Functions, Impure Functions and partial function

    In this article we will see Scala functions, closure,  Pure Functions, Impure Functions and partial function

    Scala Functions(Methods)

    Scala functions or methods are similar to Java but heavily used as Scala is a functional programming language. We use the def keyword while writing definition of function.

    Syntax:

    <access type> def <functionName>: <Retrun Type> = {
    //definition of function
    }

    Another Syntax for Single Line Function:

    def <functionName>: <Retrun Type> = <one line code>

    Example of function:

    object Loops {
     
      def myFirstFunction(): String = {
    	println("My first function")
    	"My first function"
      }
     
      private def myOneLineFunction() = println("I am one line function")
     
      def main(args: Array[String]): Unit = { //A function called main
    	myFirstFunction()
    	myOneLineFunction()
      }
    }

    Output

    My first function
    I am one line function

    Scala Closure

    Closure is a way to write functions in Scala which can be saved in a variable also, it may take some variables outside the function and return some results, so in Scala a variable can hold a function, a function can take function as variable and even return function.

    Example of Closure:

    object FunctionsInScala {
     
      val b = 2
      val c = 3
      def myClosureDoubleIt(a: Int) = a*b
      val myClosureTripleIt= (a: Int) => a*c
     
      def main(args: Array[String]): Unit = {
    	println("Using myClosureDoubleIt"+myClosureDoubleIt(10))
    	println("Using myClosureTripleIt"+myClosureTripleIt(10))
      }
    }

    Output

    Using myClosureDoubleIt20
    Using myClosureTripleIt30

    Scala Pure Function

    In Scala if a function is pure it won’t mutate or change values and will always give same output for same input.

    Here are details:

    • A function f is pure if, given the same output for the same input each time.
    • Functions output is dependent on input and logic.
    • It calculates output and does not change anything else.
    • It doesn’t update input values
    • It doesn’t mutate.
    • It doesn’t have any “back doors” and does not read from the console etc.

    Examples of Pure function:

    These String methods are also pure functions:

    isEmpty
    length
    substring

    Custom Pure Method Example:

    object PureMethodsExample {
    def sum(a: Int, b: Int) = a+b
    }

    Scala Impure Functions

    A function which does not give the same output for the same input, which mutates the state of input and interacts with things outside for example interaction to console etc. is called impure method.

    Features of impure methods

    • It can mutate states of input
    • It may give different output for the same input.
    • It interacts with consoles and other things outside the method.

    Example of Impure Functions

    println()
    print()

    Custom Example of Impure Functions

    myImpureSum() function is changing the value of some Value outside its scope and doing println() which interacts with the console.

    object FunctionsInScala {
    var someValue = 10
    def myImpureSum(a: Int, b: Int) = {
    someValue = 20
    println("Doing some sum work")
    a+b+someValue
     }
    }

    Partial function

    A partial function is such a function which returns output for some input values but does not return output for every input or simply not defined for some other values. Usually a function gives output for every input but in partial functions it sometimes is not defined for certain inputs and we can check it as well.

    Implementing Partial Function with appy and isDefinedAt Methods

    To create a partial function we have to implement apply() and isDefinedAt() methods where apply method is used to do operation and isDefinedAt() tells if this method works for input or not.

     
    object PartialFunctions {
     
      val doubleThePositiveNumber = new PartialFunction[Int, Int] {
    	def apply(data: Int) = data*2
    	def isDefinedAt(data: Int) = data >0
      }
     
      def main(args: Array[String]): Unit = {
    	println(doubleThePositiveNumber(10))
      }
    }
    

    Output

    20

    Implementing Partial Function with Case

    We can use case class as well to create partial functions, check below example function divideUsingMyInt has a case which is defined for certain inputs only.

    object PartialFunctions {
     
    val divideUsingMyInt: PartialFunction[Int, Int] = {
    	case data: Int if data != 0 => 100 / data
      }
     
      def main(args: Array[String]): Unit = {
    	    println(divideUsingMyInt(10))
      }
     
    }
    

    Output

    10

    Function Chaining, orElse and andThen in Partial Function

    orElse – By using orElse we can combine and create a new partial function using two existing partial functions where one function servers some inputs and another servers another set of inputs.

    andThen – By using it we can chain the inputs from one to another partial functions.

    Example:

    doublePostiveAndNegative partial function is created using two other partial functions and features of both are combined in this.

    object PartialFunctions {
     
      val doubleThePositiveNumber = new PartialFunction[Int, Int] {
    	def apply(data: Int) = data*2
    	def isDefinedAt(data: Int) = data >0
      }
     
      val doubleTheNegativeNumber = new PartialFunction[Int, Int] {
    	def apply(data: Int) = data*2
    	def isDefinedAt(data: Int) = data < 0
      }
     
      val doublePostiveAndNegative = {
    	doubleThePositiveNumber orElse doubleTheNegativeNumber
      }
      val tripleData = new PartialFunction[Int, Int] {
    	def apply(data: Int) = data*3
    	def isDefinedAt(data: Int) = data < 0
      }
     
      def main(args: Array[String]): Unit = {
    	val orElseUsed = doublePostiveAndNegative(-10)
    	val andThenUsed = (doublePostiveAndNegative andThen tripleData)(-1)
      }
    }

    Reference

    Next Article

    • Higher order functions(HOD), Currying and Pattern Matching

















  • Leave a Reply

    Your email address will not be published. Required fields are marked *