Tutorials Hut

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 *

    Scroll to Top