Page Contents
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.
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) }