Scala – Functions

  • Post category:Scala
  • Reading time:10 mins read

What is Scala Function ?

Scala supports functional programming approach. It provides rich set of built-in functions and allows you to create user defined functions also.In Scala, functions are first class values. You can store function value, pass function as an argument and return function as a value from other function. You can create function by using def keyword. You must mention return type of parameters while defining function and return type of a function is optional. If you don’t specify return type of a function, default return type is Unit.

Scala has both functions and methods and we use the terms method and function interchangeably with a minor difference. A Scala method is a part of a class which has a name, a signature, optionally some annotations, and some bytecode where as a function in Scala is a complete object which can be assigned to a variable. In other words, a function, which is defined as a member of some object, is called a method.

NOTE: Scala function’s name can have characters like +, ++, ~, &,-, –, \, /, :, etc.

Function Declarations

def functionName ([list of parameters]) : [return type]

Methods are implicitly declared abstract if you don’t use the equals sign and the method body.

Scala function declaratoin

Function Definitions

Syntax

def functionName ([list of parameters]) : [return type] = {
   function body
   return [expr] 
}

NOTE :

  • “return” keyword is not mandatory.
  • Return type is only mandatory for a recursive function.

Here, return type could be any valid Scala data type and list of parameters will be a list of variables separated by comma and list of parameters and return type are optional. Very similar to Java, a return statement can be used along with an expression in case function returns a value.

Example – Function to add two numbers.

object Test {
   def addInt( a:Int, b:Int ) : Int = {
      a + b
   }
}

Example – Function returning Unit

Unit return type is used for a function that does not return anything. Unit is equivalent to void in Java.

A function which does not return anything is called a Procedure.

Here is the syntax −

object Hello{
   def printMe( ) : Unit = {
      println("Hello, Scala!")
   }
}

How to call a function ?

Scala provides a number of syntactic variations for invoking methods. Following is the standard way to call a method −

functionName( list of parameters )

If a function is being called using an instance of the object, then we would use dot notation similar to Java as follows −

[instance.]functionName( list of parameters )

Example

object Demo extends App {
   def main(args: Array[String]) {
      println( "The sum is: " + addInt(5,5) );
   }
   
   def addInt( a:Int, b:Int ) : Int = {
      a + b
   }
}

Output

Returned Value : 10

Some Function examples

Example – Recursive function

The process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called as recursive function.

object Demo extends App {
   def main(args: Array[String]) {
      println( "Factorial of 4 is: " + fact(4) );
   }

   def fact(x: Int): Int = {
      if (x == 0) 1 else fact(x - 1)
   }
}

Output

24

Higher Order Functions

Higher order functions take other functions as parameters or return a function as a result. This is possible because functions are first-class values in Scala.

One of the most common examples is the higher-order function map which is available for collections in Scala.

Example

val sal= Seq(100, 200, 300) 
val doubleSalary = (x: Int) => x * 2 val 
salNew= sal.map(doubleSalary) 

Output

List(200, 400, 600)

Coercing methods into functions

It is also possible to pass methods as arguments to higher-order functions because the Scala compiler will coerce the method into a function.

Example

object MethodCoercing extends App {
   val x = new ConvertTemperature(List(100.0,101.1,102.3))
   println(x.forecastInFahrenheit)
}

class ConvertTemperature(temperatures: List[Double]){
   private def convertCtoF(temp: Double) = temp * 1.8 + 32

   def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF)
}

Output

List(212.0, 213.98, 216.14)

Explanation : In the above example, the method convertCtoF is passed to the higher order function map. This is possible because the compiler coerces convertCtoF to the function e => convertCtoF(e) ( Note:e will be a generated name which is guaranteed to be unique within its scope ).

Functions that accept functions

Higher-order functions reduce redundant code. Lets say we want to create a function that calculates sum of int values from a to b or sum of cubes from a to b, we can write a code as mentioned below

object Test extends App {
   def sumInts(a: Int, b: Int): Int = {
      if (a > b) 0 else a + sumInts(a + 1, b)
   }

   def sumCubes(a: Int, b: Int): Int = {
      if (a > b) 0 else cube(a) + sumCubes(a + 1, b)
   }

   def cube(x: Int): Int = { x * x * x }

   println(sumInts(3, 5)) 
   println(sumCubes(3, 5))
}

We can write the same code using a higher-order function

object HigherOrderFuncExample extends App {
   def sum(f: Int => Int, a: Int, b: Int): Int = {
      if (a > b) {
         return 0
      } else {
         return f(a) + sum(f, a + 1, b)
      }
   }

   // Calculating Sum of Cubes using the higher-order function.
   def sumCube(a: Int, b: Int) = { sum(n => n * n * n, a, b) }
   println(sumCube(1, 3))

   // Calculating Sum of Ints using the higher-order function.
   def sumInts(a: Int, b: Int) = { sum(n => n, a, b) }
   println(sumInts(1, 3))

   // Calculating Sum of factorials using the higher-order function.
   def fact(x: Int): Int = {
      if (x == 0) 1 else fact(x - 1)
   }
   def sumFact(a: Int, b: Int) = { sum(fact, a, b) }
   println(sumFact(1, 3))
}

Output

36
6
3

In the above example, the function sum is a higher order function. The first argument is a function itself ( f: Int => Int). The same function can calculate sum of Int, sum of Cubes etc.

Functions that return functions

We can also write a function that can return a function.

Example

object FuncReturningFunc extends App {
   def urlBuilder(ssl: Boolean, dom: String): (String, String) => String = {
      val schema = if (ssl) { "https://" } else { "http://" }

      // Returning a function
      (endpoint: String, query: String) => s"$schema$dom"
   }

   val domain = "www.proedu.co"
   def getURL = urlBuilder(true, domain)
   val endpoint = "user"
   val query = "id=1001"
   val url = getURL(endpoint, query) 
   println(url)
}

Output